Skip to content

Commit 7b5f394

Browse files
authored
Merge pull request #3212 from BsAtHome/hm2_spix-backport-2.9
Hm2_spix driver backport to 2.9
2 parents 9b4466d + f46d119 commit 7b5f394

17 files changed

Lines changed: 4022 additions & 35 deletions

File tree

docs/man/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ man9/gearchange.9
109109
man9/gray2bin.9
110110
man9/histobins.9
111111
man9/homecomp.9
112+
man9/hm2_spix.9
112113
man9/hypot.9
113114
man9/ilowpass.9
114115
man9/integ.9

docs/src/man/man9/hm2_spix.9.adoc

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
= hm2_spix(9)
2+
3+
== NAME
4+
5+
hm2_spix - LinuxCNC HAL driver for the Mesa Electronics Anything IO
6+
boards with SPI enabled HostMot2 firmware.
7+
8+
== SYNOPSIS
9+
10+
*loadrt hm2_spix*
11+
12+
____
13+
*config* [default: ""]::
14+
HostMot2 config strings, described in the *hostmot2*(9) manpage.
15+
*spiclk_rate* [default: 25000]::
16+
Specify the SPI clock rate in kHz for each probed board. See *SPI
17+
CLOCK RATES* below. Each entry follows the *spi_probe* setting, where
18+
each probe takes the next value of the *spi_rate* list. A *spi_rate*
19+
of 0 (zero) or less automatically selects the first rate in the list.
20+
You may truncate the list to the number of boards you use.
21+
*spiclk_rate_rd* [default: same as *spiclk_rate*]::
22+
Specify the SPI read clock rate in kHz. Usually you read and write at
23+
the same speed. However, you may want to reduce the reading speed if
24+
the round-trip is too long (see *SPI CLOCK RATES* below). You may
25+
truncate the list to the number of boards you use.
26+
*spi_probe* [default: 1]::
27+
Probe SPI port and CE lines for a card. This is a bit-field indicating
28+
which combinations of SPI and CE should be probed: - 1 = SPI0/CE0, - 2
29+
= SPI0/CE1, - 4 = SPI1/CE0, - 8 = SPI1/CE1, - 16 = SPI1/CE2. +
30+
The probe is performed exactly in above order. Any boards found will
31+
be numbered 0...4 in the order found. It is an error if a probe fails
32+
and the driver will abort. See also *INTERFACE CONFIGURATION* below.
33+
*force_driver* [default: <auto probe>]::
34+
Force a specific hardware driver to be selected. This is usually not
35+
necessary and the hm2_spix driver will normally select the appropriate
36+
hardware driver automatically. See also *HARDWARE DRIVERS* below.
37+
*spidev_path* [default: <empty>]::
38+
Override the device node path to the spidev device. Default is
39+
/dev/spidevX.Y, where X.Y is {0.0, 0.1, 1.0, 1.1, 1.2} in that order.
40+
This option has only effect if the spix_spidev hardware driver is
41+
selected or forced to be used.
42+
*spi_noqueue* [default: 0 (off)]::
43+
Force disable queued command processing. Normally, all requests are
44+
queued if requested by upstream and sent in one bulk transfer. This
45+
reduces overhead significantly by up to 35%. Disabling the queue makes
46+
each transfer visible and more easily debug-able. Set to any non-zero
47+
value to disable the queue.
48+
*spi_debug* [default: -1]::
49+
Set the message level of the running process. The message level is set
50+
if *spi_debug* is set to a positive value between 0 and 5, where 0 means
51+
no messages at all and 5 means everything. A value of -1 does not touch
52+
the current message level. +
53+
Caveat Emptor: changing the message level is process-wide and all
54+
modules within the process will spit out messages at the requested
55+
level. This may cause quite some clutter in your terminal.
56+
____
57+
58+
== DESCRIPTION
59+
60+
hm2_spix is a device driver for all computer boards with an available
61+
SPI port, including Raspberry Pi 3, 4 and 5. The SPI port interfaces
62+
with Mesa's SPI based Anything I/O boards with SPI enabled HostMot2
63+
firmware to the LinuxCNC HAL.
64+
65+
This driver unifies all previous hostmot2 SPI hal drivers in one with
66+
dedicated hardware drivers for Raspberry Pi models 3, 4 and 5 and has a
67+
fall-back to spidev for unknown boards. Further hardware drivers may be
68+
created and integrated when requested.
69+
70+
The supported Mesa boards are: 7I90HD, 7I43, 7C80 and 7C81.
71+
72+
The board must have a compatible firmware (like: 7i90_spi_*-bit,
73+
7c80_*.bit and 7c81_*.bit) loaded on the board by the *mesaflash*(1)
74+
program.
75+
76+
hm2_spix is only available when LinuxCNC is configured with "uspace"
77+
realtime. It works with Raspian and PREEMPT_RT kernel.
78+
79+
See also *NOTES* below.
80+
81+
== HARDWARE DRIVERS
82+
83+
The following hardware drivers are implemented and probed in order:
84+
|===
85+
| Driver | Board
86+
87+
| spix_rpi3
88+
| RPi3B, RPi3A+, RPi3B+, RPi4B, RPi4CM
89+
90+
| spix_rpi5
91+
| RPi5B, RPi5CM
92+
93+
| spix_spidev
94+
| Any board not recognised
95+
|===
96+
97+
Probing the hardware is implemented by matching known computer boards
98+
against the device-tree compatible string-list from
99+
/proc/device-tree/compatible. Normally, the first hardware driver giving
100+
a match will be selected. However, it is possible to force a specific
101+
driver to be used using the *force_driver* option with the name of the
102+
driver you want to use.
103+
104+
== INTERFACE CONFIGURATION
105+
106+
Up to five device boards are supported. Two on SPI0 and three on SPI1.
107+
It is recommended that you, at most, use two devices and each device
108+
connected to a separate SPI port. You can choose which CE lines you
109+
prefer or fit your design and setup. Use the *spi_probe* parameter to
110+
instruct the driver where to search for the board(s).
111+
112+
For the Mesa 7C80 and 7C81 you'll always want to configure SPI0/CE0.
113+
These boards have a matching 40-pin header for the computer board.
114+
115+
The SPI ports are located on the 40-pin header for those computer boards
116+
with a compatible header. The GPIO numbers are only guaranteed to be
117+
valid for Raspberry Pi boards.
118+
119+
Port SPI0:
120+
[cols=",>,>,"]
121+
|===
122+
| Pin | GPIO | 40-pin | Devname
123+
| MOSI | 10 | 19 |
124+
| MISO | 9 | 21 |
125+
| SCLK | 11 | 23 |
126+
| CE0 | 8 | 24 | /dev/spidev0.0
127+
| CE1 | 7 | 26 | /dev/spidev0.1
128+
|===
129+
130+
Port SPI1:
131+
[cols=",>,>,"]
132+
|===
133+
| Pin | GPIO | 40-pin | Devname
134+
| MOSI | 20 | 38 |
135+
| MISO | 19 | 35 |
136+
| SCLK | 21 | 40 |
137+
| CE0 | 18 | 12 | /dev/spidev1.0
138+
| CE1 | 17 | 11 | /dev/spidev1.1
139+
| CE2 | 16 | 36 | /dev/spidev1.2
140+
|===
141+
142+
== REALTIME PERFORMANCE OF THE HM2_SPIX DRIVER
143+
144+
Using a RPi3 will work, but is not the best option. Currently, the RPi4
145+
is known to work adequately. The newer RPi5 is a lot faster and will
146+
normally run a servo-thread at 1 kHz without problems.
147+
148+
All other computer boards and LinuxCNC configurations need to be tested
149+
thoroughly.
150+
151+
All other parameters: TBD.
152+
153+
== SPI CLOCK RATES
154+
155+
The SPI driver can provide frequencies beyond what is acceptable for any
156+
board. A safe value to start with would be 12.5 MHz (spiclk_rate=12500)
157+
and then work your way up from there.
158+
159+
The SPI driver generates (very) discrete clock frequencies, especially
160+
in the high MHz range because of a simple clock divider structure. The
161+
base frequency is different between boards and the divider for SPI0/SPI1
162+
scales using discrete factors with formula f=trunc(base/(2*divider)). The
163+
following list specifies the highest possible *spiclk_rate* and
164+
*spiclk_rate_rd* frequencies (in kHz) for discrete divider settings:
165+
|===
166+
| ^| RPi3 ^| RPi4 ^| RPi5
167+
| Base >| 400 MHz >| 500 MHz >| 200 MHz
168+
| Fastest >| 50000 >| 50000 >| 50000
169+
| >| 40000 >| 41666 >| 33333
170+
| >| 33333 >| 35714 >| 25000
171+
| >| 28571 >| 31250 >| 20000
172+
| >| 25000 >| 27777 >| 16666
173+
| >| 22222 >| 25000 >| 14285
174+
| >| 20000 >| 22727 >| 12500
175+
| >| 18181 >| 20833 >| 11111
176+
| >| 16666 >| 19230 >| 10000
177+
| >| 15384 >| 17857 >| 9090
178+
| >| ... >| ... >| ...
179+
| Slowest >| SPI0:4 >| SPI0:4 >| SPI0:4
180+
| Slowest >| SPI1:49 >| SPI1:62 >| SPI1:4
181+
|===
182+
183+
Note that the clock rate setting is heavily influenced by rounding and may be
184+
higher than expected if the divider rounds to the next lower value. You can
185+
check the actual clock rate by enabling informational messages (set
186+
*spi_debug*=3).
187+
188+
The slowest selectable SPI clock frequency for SPI0 and SPI1 are not for
189+
production systems. They can be selected for testing purposes. You
190+
should not expect any real-time performance with such slow setting.
191+
192+
The highest theoretically possible SPI clock frequency is higher than
193+
stated in the above table. However, you will not be able to build any
194+
reliable hardware interface at that frequency. The driver limits the
195+
clock to 50.0 MHz (cpiclk_rate=50000). The Mesa board interface supports
196+
frequencies up to 50 MHz and that is with good cabling in write
197+
direction only.
198+
199+
Writing to the Mesa board may be done faster than reading. This is
200+
especially important if you have "long" wires or any buffers on the
201+
SPI-bus path. You can set the read clock frequency to a lower value
202+
(using *spiclk_rate_rd*) to counter the effects of the SPI-bus
203+
round-trip needed for read actions. For example, you can write at 33.33
204+
MHz and read at 25.00 MHz.
205+
206+
The maximum SPI clock of the spix_rpi5 driver has been tested up to
207+
50 MHz write speed and 33 MHz read speed on the 7C80 and 7C81. However,
208+
it is not recommended to run at the limit on production systems. A safe
209+
setting would be to set one step below the maximum speeds.
210+
211+
== NOTES
212+
213+
If you know your setup and do not require the spix_spidev driver, then
214+
it is *strongly* recommended that you unload/disable the kernel's SPI
215+
drivers *dw_spi* and *dw_spi_mmio* for the RPi5 or *spi_bmc2835* for the
216+
RPi3 and RPi4. The hm2_spix hardware drivers attempt to unload the
217+
kernel driver at startup if detected and restore it at exit if initially
218+
loaded. However, there are no guarantees about the effectiveness of the
219+
module unload/load actions.
220+
221+
*Warning*: having both kernel and user-space SPI drivers installed can
222+
result in unexpected interactions and system instabilities.
223+
224+
The Raspberry Pi *must* have an adequate power supply. At high speeds
225+
and noise on the supply, there is the possibility of strange behaviour
226+
if the noise gets out of hand.
227+
228+
The Mesa 7C80 provides enough local power to the host via the 40-pin
229+
interface header if your external power supply is adequate (on connector
230+
TB6). The Mesa 7C81 needs an adequate external 5V power supply (on
231+
connector TB1) and feeds it directly to the host interface header.
232+
233+
For the Raspberry Pi 4: Be sure to have a proper heat-sink mounted on
234+
the SoC or it will get too warm and may crash.
235+
236+
For the Raspberry Pi 5: Be sure to have a proper *active* heat-sink
237+
mounted on the SoC or it will get too warm and may crash.
238+
239+
== SEE ALSO
240+
241+
hostmot2(9)
242+
243+
== LICENSE
244+
245+
GPL

src/Makefile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,7 @@ endif
10141014

10151015
obj-$(CONFIG_HOSTMOT2) += hostmot2.o hm2_test.o hm2_pci.o hm2_7i43.o hm2_7i90.o setsserial.o
10161016
ifeq ($(BUILD_SYS),uspace)
1017-
obj-$(CONFIG_HOSTMOT2) += hm2_eth.o hm2_spi.o hm2_rpspi.o
1017+
obj-$(CONFIG_HOSTMOT2) += hm2_eth.o hm2_spi.o hm2_rpspi.o hm2_spix.o
10181018
endif
10191019
hostmot2-objs := \
10201020
hal/drivers/mesa-hostmot2/hostmot2.o \
@@ -1065,6 +1065,14 @@ hm2_spi-objs := \
10651065
hm2_rpspi-objs := \
10661066
hal/drivers/mesa-hostmot2/hm2_rpspi.o \
10671067
$(MATHSTUB)
1068+
hm2_spix-objs := \
1069+
hal/drivers/mesa-hostmot2/hm2_spix.o \
1070+
hal/drivers/mesa-hostmot2/spix_rpi5.o \
1071+
hal/drivers/mesa-hostmot2/spix_rpi3.o \
1072+
hal/drivers/mesa-hostmot2/spix_spidev.o \
1073+
hal/drivers/mesa-hostmot2/llio_info.o \
1074+
hal/drivers/mesa-hostmot2/eshellf.o \
1075+
$(MATHSTUB)
10681076
hm2_test-objs := \
10691077
hal/drivers/mesa-hostmot2/hm2_test.o \
10701078
hal/drivers/mesa-hostmot2/bitfile.o \
@@ -1341,6 +1349,7 @@ endif
13411349
../rtlib/hm2_eth$(MODULE_EXT): $(addprefix objects/rt,$(hm2_eth-objs))
13421350
../rtlib/hm2_spi$(MODULE_EXT): $(addprefix objects/rt,$(hm2_spi-objs))
13431351
../rtlib/hm2_rpspi$(MODULE_EXT): $(addprefix objects/rt,$(hm2_rpspi-objs))
1352+
../rtlib/hm2_spix$(MODULE_EXT): $(addprefix objects/rt,$(hm2_spix-objs))
13441353
../rtlib/hal_bb_gpio$(MODULE_EXT): $(addprefix objects/rt,$(hal_bb_gpio-objs))
13451354
../rtlib/hal_pi_gpio$(MODULE_EXT): $(addprefix objects/rt,$(hal_pi_gpio-objs))
13461355
ifdef LIBGPIOD_VER
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* This is a component for RaspberryPi and other boards for linuxcnc.
3+
* Copyright (c) 2024 B.Stultiens <lcnc@vagrearg.org>
4+
*
5+
* This program is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License as published by the Free
7+
* Software Foundation; either version 2 of the License, or (at your option)
8+
* any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13+
* more details.
14+
*
15+
* You should have received a copy of the GNU General Public License along with
16+
* this program; if not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
#ifndef HAL_HM2_DTCBOARDS_H
19+
#define HAL_HM2_DTCBOARDS_H
20+
21+
/*
22+
* Info about the hardware platform, see:
23+
* https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#best-practices-for-revision-code-usage
24+
* https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#check-raspberry-pi-model-and-cpu-across-distributions
25+
*
26+
* Reading /proc/device-tree/compatible should contain the relevant
27+
* information. We should get a buffer containing a string-list like:
28+
* "raspberrypi,5-model-b\0brcm,bcm2712\0"
29+
* And yes, it has embedded NULs.
30+
*
31+
* The idea is to match one of the strings to assign the correct driver for the
32+
* specific board.
33+
*/
34+
#define DTC_BOARD_MAKE_RPI "raspberrypi"
35+
36+
#define DTC_BOARD_RPI_5CM "5-compute-module"
37+
#define DTC_BOARD_RPI_5B "5-model-b"
38+
#define DTC_BOARD_RPI_4CM "4-compute-module"
39+
#define DTC_BOARD_RPI_4B "4-model-b"
40+
#define DTC_BOARD_RPI_3CM "3-compute-module"
41+
#define DTC_BOARD_RPI_3BP "3-model-b-plus"
42+
#define DTC_BOARD_RPI_3AP "3-model-a-plus"
43+
#define DTC_BOARD_RPI_3B "3-model-b"
44+
#define DTC_BOARD_RPI_2B "2-model-b"
45+
#define DTC_BOARD_RPI_CM "compute-module"
46+
#define DTC_BOARD_RPI_BP "model-b-plus"
47+
#define DTC_BOARD_RPI_AP "model-a-plus"
48+
#define DTC_BOARD_RPI_BR2 "model-b-rev2"
49+
#define DTC_BOARD_RPI_B "model-b"
50+
#define DTC_BOARD_RPI_A "model-a"
51+
#define DTC_BOARD_RPI_ZERO_2W "model-zero-2-w"
52+
#define DTC_BOARD_RPI_ZERO_W "model-zero-w"
53+
#define DTC_BOARD_RPI_ZERO "model-zero"
54+
55+
#define DTC_SOC_MAKE_BRCM "brcm"
56+
57+
#define DTC_SOC_MODEL_BCM2712 "bcm2712"
58+
#define DTC_SOC_MODEL_BCM2711 "bcm2711"
59+
#define DTC_SOC_MODEL_BCM2837 "bcm2837"
60+
#define DTC_SOC_MODEL_BCM2836 "bcm2836"
61+
#define DTC_SOC_MODEL_BCM2835 "bcm2835"
62+
63+
/* The device-tree compatible strings for the boards */
64+
#define DTC_RPI_SOC_BCM2712 DTC_SOC_MAKE_RPI "," DTC_SOC_MODEL_BCM2712
65+
#define DTC_RPI_MODEL_5CM DTC_BOARD_MAKE_RPI "," DTC_BOARD_RPI_5CM
66+
#define DTC_RPI_MODEL_5B DTC_BOARD_MAKE_RPI "," DTC_BOARD_RPI_5B
67+
68+
#define DTC_RPI_SOC_BCM2711 DTC_SOC_MAKE_RPI "," DTC_SOC_MODEL_BCM2711
69+
#define DTC_RPI_MODEL_4CM DTC_BOARD_MAKE_RPI "," DTC_BOARD_RPI_4CM
70+
#define DTC_RPI_MODEL_4B DTC_BOARD_MAKE_RPI "," DTC_BOARD_RPI_4B
71+
72+
#define DTC_RPI_SOC_BCM2837 DTC_SOC_MAKE_BRCM "," DTC_SOC_MODEL_BCM2837
73+
#define DTC_RPI_MODEL_3CM DTC_BOARD_MAKE_RPI "," DTC_BOARD_RPI_3CM
74+
#define DTC_RPI_MODEL_3BP DTC_BOARD_MAKE_RPI "," DTC_BOARD_RPI_3BP
75+
#define DTC_RPI_MODEL_3AP DTC_BOARD_MAKE_RPI "," DTC_BOARD_RPI_3AP
76+
#define DTC_RPI_MODEL_3B DTC_BOARD_MAKE_RPI "," DTC_BOARD_RPI_3B
77+
#define DTC_RPI_MODEL_ZERO_2W DTC_BOARD_MAKE_RPI "," DTC_BOARD_RPI_ZERO_2W
78+
79+
/* Older than a RPi3 (bcm2836 and bcm2835) is probably not a good idea to use. */
80+
81+
#endif
82+
// vim: ts=4

0 commit comments

Comments
 (0)