Skip to content

Commit c09dfb3

Browse files
msierszulskicfriedt
authored andcommitted
drivers: fpga controller: add shell support
This adds shell support for FPGA drivers. Signed-off-by: Mateusz Sierszulski <[email protected]> Signed-off-by: Tomasz Gorochowik <[email protected]>
1 parent a64ce1f commit c09dfb3

File tree

9 files changed

+5703
-0
lines changed

9 files changed

+5703
-0
lines changed

drivers/fpga/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
zephyr_library()
44

55
zephyr_library_sources_ifdef(CONFIG_EOS_S3_FPGA fpga_eos_s3.c)
6+
zephyr_library_sources_ifdef(CONFIG_FPGA_SHELL fpga_shell.c)

drivers/fpga/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ module = fpga
1414
module-str = fpga
1515
source "subsys/logging/Kconfig.template.log_config"
1616

17+
config FPGA_SHELL
18+
bool "Enable FPGA Shell"
19+
depends on SHELL && FPGA
20+
help
21+
Enable FPGA Shell support.
22+
1723
source "drivers/fpga/Kconfig.eos_s3"
1824

1925
endif # FPGA

drivers/fpga/fpga_shell.c

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* Copyright (c) 2021 Antmicro <www.antmicro.com>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <sys/printk.h>
8+
#include <shell/shell.h>
9+
#include <version.h>
10+
#include <stdlib.h>
11+
#include <drivers/fpga.h>
12+
13+
static int parse_common_args(const struct shell *sh, char **argv,
14+
const struct device **dev)
15+
{
16+
*dev = device_get_binding(argv[1]);
17+
if (!*dev) {
18+
shell_error(sh, "FPGA device %s not found", argv[1]);
19+
return -ENODEV;
20+
}
21+
return 0;
22+
}
23+
24+
static int cmd_on(const struct shell *sh, size_t argc, char **argv)
25+
{
26+
const struct device *dev;
27+
int err;
28+
29+
err = parse_common_args(sh, argv, &dev);
30+
if (err < 0) {
31+
return err;
32+
}
33+
34+
shell_print(sh, "%s: turning on", dev->name);
35+
36+
err = fpga_on(dev);
37+
if (err) {
38+
shell_error(sh, "Error: %d", err);
39+
}
40+
41+
return err;
42+
}
43+
44+
static int cmd_off(const struct shell *sh, size_t argc, char **argv)
45+
{
46+
const struct device *dev;
47+
int err;
48+
49+
err = parse_common_args(sh, argv, &dev);
50+
if (err < 0) {
51+
return err;
52+
}
53+
54+
shell_print(sh, "%s: turning off", dev->name);
55+
56+
err = fpga_off(dev);
57+
if (err) {
58+
shell_error(sh, "Error: %d", err);
59+
}
60+
61+
return err;
62+
}
63+
64+
static int cmd_reset(const struct shell *sh, size_t argc, char **argv)
65+
{
66+
const struct device *dev;
67+
int err;
68+
69+
err = parse_common_args(sh, argv, &dev);
70+
if (err < 0) {
71+
return err;
72+
}
73+
74+
shell_print(sh, "%s: resetting FPGA", dev->name);
75+
76+
err = fpga_reset(dev);
77+
if (err) {
78+
shell_error(sh, "Error: %d", err);
79+
}
80+
81+
return err;
82+
}
83+
84+
static int cmd_load(const struct shell *sh, size_t argc, char **argv)
85+
{
86+
const struct device *dev;
87+
int err;
88+
89+
err = parse_common_args(sh, argv, &dev);
90+
if (err < 0) {
91+
return err;
92+
}
93+
94+
shell_print(sh, "%s: loading bitstream", dev->name);
95+
96+
fpga_load(dev, (uint32_t *)strtol(argv[2], NULL, 0),
97+
(uint32_t)atoi(argv[3]));
98+
99+
return err;
100+
}
101+
102+
static int cmd_get_status(const struct shell *sh, size_t argc, char **argv)
103+
{
104+
const struct device *dev;
105+
int err;
106+
107+
err = parse_common_args(sh, argv, &dev);
108+
if (err < 0) {
109+
return err;
110+
}
111+
112+
shell_print(sh, "%s status: %d", dev->name, fpga_get_status(dev));
113+
114+
return err;
115+
}
116+
117+
static int cmd_get_info(const struct shell *sh, size_t argc, char **argv)
118+
{
119+
const struct device *dev;
120+
int err;
121+
122+
err = parse_common_args(sh, argv, &dev);
123+
if (err < 0) {
124+
return err;
125+
}
126+
127+
shell_print(sh, "%s", fpga_get_info(dev));
128+
129+
return err;
130+
}
131+
132+
SHELL_STATIC_SUBCMD_SET_CREATE(
133+
sub_fpga, SHELL_CMD_ARG(off, NULL, "<device>", cmd_off, 2, 0),
134+
SHELL_CMD_ARG(on, NULL, "<device>", cmd_on, 2, 0),
135+
SHELL_CMD_ARG(reset, NULL, "<device>", cmd_reset, 2, 0),
136+
SHELL_CMD_ARG(load, NULL, "<device> <address> <size in bytes>",
137+
cmd_load, 4, 0),
138+
SHELL_CMD_ARG(get_status, NULL, "<device>", cmd_get_status, 2, 0),
139+
SHELL_CMD_ARG(get_info, NULL, "<device>", cmd_get_info, 2, 0),
140+
SHELL_SUBCMD_SET_END);
141+
142+
SHELL_CMD_REGISTER(fpga, &sub_fpga, "FPGA commands", NULL);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.13)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(fpga_controller)
6+
7+
target_sources(app PRIVATE src/main.c)
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Zephyr FPGA controller in shell
2+
This module is an FPGA driver that can easily load a bitstream, reset it, check its status, enable or disable the FPGA.
3+
This sample demonstrates how to use the FPGA controller shell subsystem.
4+
Currently, the sample works with the [QuickLogic QuickFeather board](https://github.com/QuickLogic-Corp/quick-feather-dev-board).
5+
6+
## Requirements
7+
* Zephyr RTOS with shell subsystem enabled
8+
* [QuickLogic QuickFeather board](https://github.com/QuickLogic-Corp/quick-feather-dev-board)
9+
10+
## Building
11+
12+
For the QuickLogic QuickFeather board:
13+
```bash
14+
west build -b quick_feather samples/drivers/fpga/fpga_controller_shell
15+
```
16+
See [QuickFeather programming and debugging](https://docs.zephyrproject.org/latest/boards/arm/quick_feather/doc/index.html#programming-and-debugging) on how to load an image to the board.
17+
18+
## Running
19+
After connecting to the shell console you should see the following output:
20+
21+
```bash
22+
Address of the bitstream (red): 0xADDR
23+
Address of the bitstream (green): 0xADDR
24+
Size of the bitstream (red): 75960
25+
Size of the bitstream (green): 75960
26+
27+
uart:~$
28+
```
29+
This sample is already prepared with bitstreams.
30+
After executing the sample, you can see at what address it is stored and its size in bytes.
31+
32+
The FPGA controller command can now be used (`fpga load <device> <address> <size in bytes>`):
33+
```bash
34+
uart:~$ fpga load FPGA 0x2001a46c 75960
35+
FPGA: loading bitstream
36+
```
37+
The LED should start blinking (color depending on the selected bitstream).
38+
To upload the bitstream again you need to reset the FPGA:
39+
40+
```bash
41+
uart:~$ fpga reset FPGA
42+
FPGA: resetting FPGA
43+
```
44+
You can also use your own bitstream.
45+
To load a bitstream into device memory, use `devmem load` command.
46+
It is important to use the -e option when sending a bistream via `xxd`:
47+
```bash
48+
uart:~$ devmem load -e 0x10000
49+
Loading...
50+
Press ctrl-x + ctrl-q to stop
51+
```
52+
Now, the loader is waiting for data.
53+
You can either type it directly from the console or send it from the host PC (replace `ttyX` with the appropriate one for your shell console):
54+
```bash
55+
xxd -p data > /dev/ttyX
56+
```
57+
(It is important to use plain-style hex dump)
58+
Once the data is transferred, use `ctrl-x + ctrl-q` to quit loader.
59+
It will print the sum of the read bytes and return to the shell:
60+
```bash
61+
Number of bytes read: 75960
62+
uart:~$
63+
```
64+
Now the bitstream can be uploaded again.
65+
```bash
66+
uart:~$ fpga load FPGA 0x10000 75960
67+
FPGA: loading bitstream
68+
```
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CONFIG_SHELL=y
2+
CONFIG_FPGA=y
3+
CONFIG_EOS_S3_FPGA=y
4+
CONFIG_FPGA_SHELL=y
5+
CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN=n
6+
CONFIG_BOOT_BANNER=n

0 commit comments

Comments
 (0)