drivers: fpga controller: add shell support
This adds shell support for FPGA drivers. Signed-off-by: Mateusz Sierszulski <msierszulski@internships.antmicro.com> Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
This commit is contained in:
parent
a64ce1fc6b
commit
c09dfb3bf6
9 changed files with 5703 additions and 0 deletions
|
@ -3,3 +3,4 @@
|
||||||
zephyr_library()
|
zephyr_library()
|
||||||
|
|
||||||
zephyr_library_sources_ifdef(CONFIG_EOS_S3_FPGA fpga_eos_s3.c)
|
zephyr_library_sources_ifdef(CONFIG_EOS_S3_FPGA fpga_eos_s3.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_FPGA_SHELL fpga_shell.c)
|
||||||
|
|
|
@ -14,6 +14,12 @@ module = fpga
|
||||||
module-str = fpga
|
module-str = fpga
|
||||||
source "subsys/logging/Kconfig.template.log_config"
|
source "subsys/logging/Kconfig.template.log_config"
|
||||||
|
|
||||||
|
config FPGA_SHELL
|
||||||
|
bool "Enable FPGA Shell"
|
||||||
|
depends on SHELL && FPGA
|
||||||
|
help
|
||||||
|
Enable FPGA Shell support.
|
||||||
|
|
||||||
source "drivers/fpga/Kconfig.eos_s3"
|
source "drivers/fpga/Kconfig.eos_s3"
|
||||||
|
|
||||||
endif # FPGA
|
endif # FPGA
|
||||||
|
|
142
drivers/fpga/fpga_shell.c
Normal file
142
drivers/fpga/fpga_shell.c
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Antmicro <www.antmicro.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/printk.h>
|
||||||
|
#include <shell/shell.h>
|
||||||
|
#include <version.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <drivers/fpga.h>
|
||||||
|
|
||||||
|
static int parse_common_args(const struct shell *sh, char **argv,
|
||||||
|
const struct device **dev)
|
||||||
|
{
|
||||||
|
*dev = device_get_binding(argv[1]);
|
||||||
|
if (!*dev) {
|
||||||
|
shell_error(sh, "FPGA device %s not found", argv[1]);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_on(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = parse_common_args(sh, argv, &dev);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
shell_print(sh, "%s: turning on", dev->name);
|
||||||
|
|
||||||
|
err = fpga_on(dev);
|
||||||
|
if (err) {
|
||||||
|
shell_error(sh, "Error: %d", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_off(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = parse_common_args(sh, argv, &dev);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
shell_print(sh, "%s: turning off", dev->name);
|
||||||
|
|
||||||
|
err = fpga_off(dev);
|
||||||
|
if (err) {
|
||||||
|
shell_error(sh, "Error: %d", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_reset(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = parse_common_args(sh, argv, &dev);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
shell_print(sh, "%s: resetting FPGA", dev->name);
|
||||||
|
|
||||||
|
err = fpga_reset(dev);
|
||||||
|
if (err) {
|
||||||
|
shell_error(sh, "Error: %d", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_load(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = parse_common_args(sh, argv, &dev);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
shell_print(sh, "%s: loading bitstream", dev->name);
|
||||||
|
|
||||||
|
fpga_load(dev, (uint32_t *)strtol(argv[2], NULL, 0),
|
||||||
|
(uint32_t)atoi(argv[3]));
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_get_status(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = parse_common_args(sh, argv, &dev);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
shell_print(sh, "%s status: %d", dev->name, fpga_get_status(dev));
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_get_info(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = parse_common_args(sh, argv, &dev);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
shell_print(sh, "%s", fpga_get_info(dev));
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_STATIC_SUBCMD_SET_CREATE(
|
||||||
|
sub_fpga, SHELL_CMD_ARG(off, NULL, "<device>", cmd_off, 2, 0),
|
||||||
|
SHELL_CMD_ARG(on, NULL, "<device>", cmd_on, 2, 0),
|
||||||
|
SHELL_CMD_ARG(reset, NULL, "<device>", cmd_reset, 2, 0),
|
||||||
|
SHELL_CMD_ARG(load, NULL, "<device> <address> <size in bytes>",
|
||||||
|
cmd_load, 4, 0),
|
||||||
|
SHELL_CMD_ARG(get_status, NULL, "<device>", cmd_get_status, 2, 0),
|
||||||
|
SHELL_CMD_ARG(get_info, NULL, "<device>", cmd_get_info, 2, 0),
|
||||||
|
SHELL_SUBCMD_SET_END);
|
||||||
|
|
||||||
|
SHELL_CMD_REGISTER(fpga, &sub_fpga, "FPGA commands", NULL);
|
|
@ -0,0 +1,7 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
project(fpga_controller)
|
||||||
|
|
||||||
|
target_sources(app PRIVATE src/main.c)
|
68
samples/drivers/fpga/fpga_controller_shell/README.md
Normal file
68
samples/drivers/fpga/fpga_controller_shell/README.md
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
# Zephyr FPGA controller in shell
|
||||||
|
This module is an FPGA driver that can easily load a bitstream, reset it, check its status, enable or disable the FPGA.
|
||||||
|
This sample demonstrates how to use the FPGA controller shell subsystem.
|
||||||
|
Currently, the sample works with the [QuickLogic QuickFeather board](https://github.com/QuickLogic-Corp/quick-feather-dev-board).
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
* Zephyr RTOS with shell subsystem enabled
|
||||||
|
* [QuickLogic QuickFeather board](https://github.com/QuickLogic-Corp/quick-feather-dev-board)
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
For the QuickLogic QuickFeather board:
|
||||||
|
```bash
|
||||||
|
west build -b quick_feather samples/drivers/fpga/fpga_controller_shell
|
||||||
|
```
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Running
|
||||||
|
After connecting to the shell console you should see the following output:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
Address of the bitstream (red): 0xADDR
|
||||||
|
Address of the bitstream (green): 0xADDR
|
||||||
|
Size of the bitstream (red): 75960
|
||||||
|
Size of the bitstream (green): 75960
|
||||||
|
|
||||||
|
uart:~$
|
||||||
|
```
|
||||||
|
This sample is already prepared with bitstreams.
|
||||||
|
After executing the sample, you can see at what address it is stored and its size in bytes.
|
||||||
|
|
||||||
|
The FPGA controller command can now be used (`fpga load <device> <address> <size in bytes>`):
|
||||||
|
```bash
|
||||||
|
uart:~$ fpga load FPGA 0x2001a46c 75960
|
||||||
|
FPGA: loading bitstream
|
||||||
|
```
|
||||||
|
The LED should start blinking (color depending on the selected bitstream).
|
||||||
|
To upload the bitstream again you need to reset the FPGA:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uart:~$ fpga reset FPGA
|
||||||
|
FPGA: resetting FPGA
|
||||||
|
```
|
||||||
|
You can also use your own bitstream.
|
||||||
|
To load a bitstream into device memory, use `devmem load` command.
|
||||||
|
It is important to use the -e option when sending a bistream via `xxd`:
|
||||||
|
```bash
|
||||||
|
uart:~$ devmem load -e 0x10000
|
||||||
|
Loading...
|
||||||
|
Press ctrl-x + ctrl-q to stop
|
||||||
|
```
|
||||||
|
Now, the loader is waiting for data.
|
||||||
|
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):
|
||||||
|
```bash
|
||||||
|
xxd -p data > /dev/ttyX
|
||||||
|
```
|
||||||
|
(It is important to use plain-style hex dump)
|
||||||
|
Once the data is transferred, use `ctrl-x + ctrl-q` to quit loader.
|
||||||
|
It will print the sum of the read bytes and return to the shell:
|
||||||
|
```bash
|
||||||
|
Number of bytes read: 75960
|
||||||
|
uart:~$
|
||||||
|
```
|
||||||
|
Now the bitstream can be uploaded again.
|
||||||
|
```bash
|
||||||
|
uart:~$ fpga load FPGA 0x10000 75960
|
||||||
|
FPGA: loading bitstream
|
||||||
|
```
|
6
samples/drivers/fpga/fpga_controller_shell/prj.conf
Normal file
6
samples/drivers/fpga/fpga_controller_shell/prj.conf
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
CONFIG_SHELL=y
|
||||||
|
CONFIG_FPGA=y
|
||||||
|
CONFIG_EOS_S3_FPGA=y
|
||||||
|
CONFIG_FPGA_SHELL=y
|
||||||
|
CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN=n
|
||||||
|
CONFIG_BOOT_BANNER=n
|
2722
samples/drivers/fpga/fpga_controller_shell/src/greenled.h
Normal file
2722
samples/drivers/fpga/fpga_controller_shell/src/greenled.h
Normal file
File diff suppressed because it is too large
Load diff
29
samples/drivers/fpga/fpga_controller_shell/src/main.c
Normal file
29
samples/drivers/fpga/fpga_controller_shell/src/main.c
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Antmicro <www.antmicro.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr.h>
|
||||||
|
#include <shell/shell.h>
|
||||||
|
#include <device.h>
|
||||||
|
#include <sys/printk.h>
|
||||||
|
#include <drivers/fpga.h>
|
||||||
|
#include "redled.h"
|
||||||
|
#include "greenled.h"
|
||||||
|
#include <eoss3_dev.h>
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
IO_MUX->PAD_21_CTRL = (PAD_E_4MA | PAD_P_PULLDOWN | PAD_OEN_NORMAL |
|
||||||
|
PAD_SMT_DISABLE | PAD_REN_DISABLE | PAD_SR_SLOW |
|
||||||
|
PAD_CTRL_SEL_AO_REG); /* Enable red led */
|
||||||
|
IO_MUX->PAD_22_CTRL = (PAD_E_4MA | PAD_P_PULLDOWN | PAD_OEN_NORMAL |
|
||||||
|
PAD_SMT_DISABLE | PAD_REN_DISABLE | PAD_SR_SLOW |
|
||||||
|
PAD_CTRL_SEL_AO_REG); /* Enable green led */
|
||||||
|
|
||||||
|
printk("Address of the bitstream (red): %p\n", &axFPGABitStream_red);
|
||||||
|
printk("Address of the bitstream (green): %p\n", &axFPGABitStream_green);
|
||||||
|
printk("Size of the bitstream (red): %d\n", sizeof(axFPGABitStream_red));
|
||||||
|
printk("Size of the bitstream (green): %d\n", sizeof(axFPGABitStream_green));
|
||||||
|
}
|
2722
samples/drivers/fpga/fpga_controller_shell/src/redled.h
Normal file
2722
samples/drivers/fpga/fpga_controller_shell/src/redled.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue