Transfer data from linux to fpga and inversely? - linux

I have booted a ubuntu on a ZedBoard. I want to transfer data between fpga and linux. For example, I want to write or read a register from linux. What is best way for doing it? I have not any idea.
Thanx.

First of all, you need to specifically say what you want to do, for example. if you want to access the IO signals on the FPGA, you need to first add the GPIO module to your system, synthesize and implement it.
Then you use the Linux GPIO Driver to access the port as it is explained in this page:
Linux GPIO Driver
The GPIO driver fits in the Linux GPIO framework which is not a char
mode driver. Yet it does provide access to the GPIO by user space
through the sysfs filesystem. This allows each GPIO signal to be read
and written in similar manner to a char mode device. The interface is
somewhat documented in the kernel tree at Documentation/gpio.txt. The
following text is aimed to augment, not replace the existing
documentation.
For other, more complex interfaces you need to create your own driver or use one of the drivers that are available and modify it to fit your needs.

Related

Non-blocking i2c read from userspace

I'm trying to read and write data off i2c in slave mode and have found several examples to do this in userspace including this most relevant one from NXP (I'm using the iMX8MQ):
https://source.codeaurora.org/external/imx/imx-test/tree/test/mxc_i2c_slave_test/mxc_i2c_slave_test.c?h=imx_4.14.78_1.0.0_ga
However, it looks like if I want to read data, it would be a polling based implementation because it looks like i2c-dev does not provide a way to register userspace callbacks when i2c data is available. Not even sure if any Linux device drivers allow doing this at all. Am I correct in assuming that there is no non-blocking and asynchronous way of doing an i2c read from userspace in slave mode?
I'm not very familiar with writing device drivers so even if I wanted to implement my own, similar to this one:
https://github.com/torvalds/linux/blob/master/drivers/i2c/i2c-slave-eeprom.c
is it a good idea to call a userspace function when data became available (for instance when the driver received an I2C_SLAVE_STOP)?

Gpio Linux conventions and names

How can we find the naming of available gpios in an arbitrary board that runs Linux and then to use the Linux commands echo "gpionumber" >/sys/class/gpio so then we can control this gpio?
Gpio and gpiocontrollers are numbered. Gpiocontrollers may have labels, but they may not be unique.
The linux kernel documentation on gpio sysfs driver can be found here and is a good read.
The linux kernel uses device tree file to know which gpiocontrollers are available to him. A gpiocontroller may have multiple gpios. Each board has it's own unique device tree compiled with the kernel or loaded at boot time.
Gpiocontrollers are identified by the register and register length they refer too, see here. You can specify the label of the gpiocontroller as described in device tree file format and you can query the gpiocontroller label using /sys/class/gpio/gpiochipN/label, they may be not unique and they don't let you identify the gpio. Also, they may change between device tree file versions.
There is no "naming", just numbering. You can query all gpios available on a particular board by just inspecting/adding the /sys/class/gpio/gpiochip*/ngpio Usually a board manufacturer/provider/seller/etc provides documentation with the kernel it ships with the board with explanation, which gpio has which number/address, like for Colibri VF61. For some popular boards it is just a matter of googling to find nice looking images with gpio numbers, like for RaspberryPi3 or

Linux: access i2c device within board_init function

(iMX6 SOC running Linux 3.0)
I need to run a few I2C transactions in my board_init function. I tried calling i2c_get_adapter, then i2c_transfer, those being available in kernel mode, but i2c_get_adapter returns NULL. It's already called imx6q_add_imx_i2c, which is a wrapper around platform_device_register_full, but that isn't enough.
I can manipulate GPIO in board_init by calling gpio_request to obtain access, and gpio_free at the end. Is there something analogous to those functions for i2c?
--- added details ---
I've got a LAN9500A USB 100Base-T Ethernet MAC connected to a LAN9303 3-port switch with a virtual PHY. The MAC has a GPIO reset line that has to be turned off before it will spring to life and enumerate on the USB. That's done in board_init because it's completely nonstandard, so we don't want to patch the stock driver to manipulate some GPIO that's not part of the device.
The problem I'm having is that even though the MAC is permanently attached to the VPHY, it's not noticing it's connected, and an "ip link show eth1" command shows NO-CARRIER. I found I can kickstart it by unmasking the VPHY's Device Ready interrupt via I2C, but I also have to mask it immediately, or I get infinite interrupts. That's not the right solution, but Microchip has been no help in showing me a better way. But we don't want to patch the MAC driver with code to fiddle with the PHY.
There is no PHY driver for this part, and the MII interface to the VPHY doesn't include any interrupt-related registers, so it must be done through I2C. Writing a PHY driver just to flip a bit on and off once seems a lot of trouble, especially for a newbie like me who's never written a driver before.
I can do it in Python in a startup script, but that, too, seems like a heavyweight solution to a lightweight problem.
That's a wrong approach. Board file supposed to register device drivers and pass important information to them, rather than act as a device driver itself. I'm not sure if what you're trying to do is even possible.
If you really need to extract something from your I2C device on a very early stage - do that in the bootloader and pass the data to kernel via cmdline (U-boot, by the way, has I2C support for a quite some time). Then later, kernel might do appropriate actions depending on what you have passed to it.

How a device driver recognise the peripheral mapping in embedded unix

In most example project for embedded system there is a system file in which we can find structures for different peripheral as well as the memory mapping of the peripheral register, in addition there is also a module per peripheral that contains basic function to manipulate the periheral like: periph_enable, periph_write, periph_read; this is the architecture i have in mind when i tackle a new project.
Actually i started to work with a BF609 but now with an embedded linux in it, my task consist in writing a communication driver with another device via UART, as usual i tried to look for the files i used to use but in vain, i can't find the mapping of the different peripheral.
I started to read this book, i undrestand that the kernel see each device like a file and that a driver is mainly the implementation of the open, close, read and writefunctions in these file but i still don't undrestand how these functions communicate with peripheral registers.
My questions:
1) How device drivers recognise the mapping of the peripheral is there sth i missed, is there any example that explain how to implement simple read and write functions via UART for example
2) Where can i find the mapping of the peripheral in the buildroot directory
Thanks in advance

I want to utilize PCA9685 chip to drive servos on beaglebone black, I see there is a linux driver, but how to utilize in C/C++. Any examples?

So I have a Beaglebone black, and a servo/led controller http://www.adafruit.com/product/815. I'd like to control it from a C/C++ program running on the included Debian Linux.
I see there is a driver included in the kernel "pwm_pca9685", and it did create some items in the /sys directory, but nothing that seems to make any sense.
So I know that at least I need to tell the module what i2c address the chip has, so how would I do that, and then how to send various pwm commands to chip?
So I ended up forgoing the use of the driver, as I was unable to find any information on it. Instead I used various ioctl calls, such as is used in this code from Adafruit: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library/blob/master/Adafruit_PWMServoDriver.cpp

Resources