AsDevices
From ArmadeusWiki
Page under construction...
Informations on this page are not guaranteed !!
AsDevices is an ARMadeus specific library that simplify APF-board devices usage for developers. This library is written to be used with C, C++, Python, (Java?) languages. The core is written in C and other languages support is done with "wrappers".
![]() | Note: This library is under development, see the Development planning. to know which functionality is finished. |
Contents |
Install AsDevices on target
The library is included in Buildroot menu, to use it just select it:
$ make menuconfig
Package Selection for the target ---> *** Armadeus specific packages *** Armadeus specific tools/utilities ---> [*] as_devices
The base library is in C, to use it with C++ or Python, select the wrapper you need. (For Python you will need to select Python interpreter before as_devices wrapper).
Generate doxygen documentation
- If doxygen isn't installed on your Linux distribution, you have to install the correct package (here on *Ubuntu):
$ sudo apt-get install doxygen
- Then go in AsDevices root directory:
$ cd target/packages/as_devices
- Generate the documentation with Doxygen:
$ doxygen Doxyfile
- Documentation has been generated in documentation.
- Open documentation with:
$ firefox documentation/index.html
Using library in C
All functions in AsDevices library are constructed on the same way. An as_*_open() function return a device structure or an int that represent the device used. All function take this device structure in first parameter, and a function as_*_close() close the device :
struct as_devicename_dev * as_devicename_open(<some parameters>); as_devicename_do-something-with-device(struct as_devicename_dev *aDev, <some parameters>); int as_devicename_close(struct as_devicename_dev *aDev);
For each library, full documentation can be found in C header in directory target/packages/as_devices/c.
I²C
as_i2c_* functions are used to access devices on i²c bus that doesn't have/need a Linux driver. If you want to access an i²c device, please find out if a driver is not already existing before using this method.
To open the bus, you have to know its number. On APF9328 and APF27 only two busses are present: number 0 and number 1. The open() function returns an int (file descriptor of the opened /dec/i2c-x), that have to be passed to all other as_i2c_* functions :
int as_i2c_open(unsigned int i2c_id);
Then depending on the complexity of the I2C device communication protocol, you can either use read()/write() (simple frames) or ioctl() with complex "read then write"/"write then read" messages.
- Example (simple write()):
#include <stdlib.h> #include <stdio.h> #include <as_devices/as_i2c.h> int my_device = 0; #define MY_DEV_ADDR 0x23 #define MY_I2C_BUS 1 unsigned char buf[10]; int ret; ... my_device = as_i2c_open(MY_I2C_BUS); if (my_device < 0) { printf("Can't init I2C port %d!!\n", MY_I2C_BUS); return -1; } as_i2c_set_slave(my_device, MY_DEV_ADDR); ... buf[0] = (unsigned char) my_val; ret = write(my_device, buf, 1); if (ret < 0) printf("Error while sending data to device !!\n"); ...
SPI
Usage
To use as_spi_* function, the spidev kernel module/interface is required. See SPI page to know how to configure it.
Once the device file /dev/spidevx.x is available from the kernel, as_spi library can be used by including the as_spi.h header in your C source code:
#include <as_devices/as_spi.h>
Full description of the API can be found in this header (target/packages/as_devices/c/as_spi.h), available on sourceforge repository.
Example
The three mains useful functions used to communicate with a slave SPI device are :
int as_spi_open(const unsigned char *aSpidev_name);
To open the /dev/spidevx.x special spi file. This function return a file handler that will be used for all othes as_spi_* function.
void as_spi_close(int aFd);
As its name said, to close the device.
uint32_t as_spi_msg(int aFd, uint32_t aMsg, size_t aLen, uint32_t aSpeed);
This function forge spi messages on MOSI pin and return MISO message.
GPIO
Usage
To use as_gpio_* functions, the gpio kernel module is required. See GPIO_Driver page to know how to configure it.
Once the device files /dev/gpio/* are available , as_gpio library can be use by including as_gpio.h header in the C source code of your application.
#include <as_devices/as_gpio.h>
Example
Two examples are given, one for lightening led D14 and one to use blocking read on switch S1. This two example are made for APF27Dev daughter card.
- Lightening led
With as_gpio, each pin port can be openned separately. The as_gpio_open() function returns a pointer on gpio pin structure declared like this:
int ret; /* for returning value */ struct as_gpio_device *pf14;
On APF27Dev, D14 is plugged on port F pin 14, then to open it :
pf14 = as_gpio_open('F', 14);
GPIO must be configured in ouput mode :
ret = as_gpio_set_pin_direction(pf14, "out");
Then to switch LED value, just use as_gpio_set_pin_value() function:
ret = as_gpio_set_pin_value(pf14, 1); /* led off */ ... ret = as_gpio_set_pin_value(pf14, 0); /* led on */
Note that because off led wiring, led polarity is inverted (to light on set 0).
Once gpio pin usage is terminated, it must be closed :
as_gpio_close(pf14);
- Pressing button
The button S1 can be used to test interrupt capability of gpio. The button is plugged on gpio port F pin 13. After declaring the as_gpio_device structure, the pin port can be opened :
struct as_gpio_device *pf13; [...] pf13 = as_gpio_open('F', 13);
To stuff must be configured before using it as interruption source, direction and IRQ mode.
direction
ret = as_gpio_set_pin_direction(pf13, "in"); /* set switch as input */
IRQ mode There is four IRQ mode :
- GPIO_IRQ_MODE_NOINT : No interrupt, the processor will ignore event on this gpio.
- GPIO_IRQ_MODE_RISING : rising edge, the processor will generate an interruption on rising edge of gpio pin.
- GPIO_IRQ_MODE_FALLING: falling edge, the processor will generate an interruption on falling edge of gpio pin.
- GPIO_IRQ_MODE_BOTH : both, the processor will generate an interruption on both rising or falling edge of gpio.
ret = as_gpio_set_irq_mode(pf13, GPIO_IRQ_MODE_FALLING); /* interrupt will be generated on pushed button */
To capture interruption, the blocking read function can be used with a timeout. If no interruption is raised after the timeout time, read function end with error value -10.
ret = as_gpio_blocking_get_pin_value(pf13, 3, 0); /* wait for interruption for 3 seconds and 0 µs) */ if(ret == -10) printf("Timeout\n");
ADC
MAX1027
AS1531
DAC
MAX5821
MCP4912
93LCXX
PWM
Usage
To use as_pwm_* functions, the kernel module imx_pwm needs to be loaded. See PWM page to know how to configure it.
Once the special files /sys/class/pwm/pwmX/* are available , as_pwm_* functions can be use by including as_pwm.h header in the C source code of your application.
#include <as_devices/as_pwm.h>
Example
#include <as_devices/as_pwm.h> ... int main(int argc, char *argv[]) { struct as_pwm_device *my_pwm; ... my_pwm = as_pwm_open(0); if (!my_pwm) printf("Can't init PWM !!\n"); as_pwm_set_frequency(my_pwm, 150); as_pwm_set_duty(my_pwm, 500); ... as_pwm_set_state(my_pwm, 1); }
LED
Using library in Python
To use AsDevices in Python, select the python wrapper in menuconfig as follow :
Package Selection for the target ---> *** Armadeus specific packages *** Armadeus specific tools/utilities ---> [*] as_devices [*] wrapper Python
And keep all .py file on target :
Package Selection for the target ---> Interpreter languages and scripting ---> python module format to install (.py sources and .pyc compiled) ---> (X) .py sources and .pyc compiled
then compile bsp and flash it on your board.
Once done, just import the module AsDevices to use all function available in library:
import AsDevices from AsDevices import AsGpio gpio = AsGpio(3) gpio.setPinDirection('out') gpio.setPinValue(1) ...
Using library in C++
SPI
- Open the spidev device given in parameters and send one byte message:
#include <iostream> #include <as_devices/cpp/as_spi.hpp> //#define APF_SPI "spidev1.2" on APF27 #define APF_SPI "spidev1.1" // on APF9328 #define CLOCK_SPEED 1200000 using namespace std; int main(int argc, char **argv) { const unsigned char* spidev_name = (const unsigned char*) APF_SPI; if (argc > 1) { spidev_name = (const unsigned char*) argv[1]; } cout << "Opening " << spidev_name << endl; AsSpi* o=new AsSpi(spidev_name); int speed = o->getSpeed(); cout << "Max speed =" << speed << endl; int mode = o->getMode(); cout << "Mode = " << mode << endl; char data = 'c'; unsigned long long result = o->msg((unsigned long long) data, sizeof(data), CLOCK_SPEED); cout << "result=" << result << endl; return 0; }
- Makefile:
CFLAGS = -I/home/xxx/buildroot/output/staging/usr/include/as_devices CFLAGS += -I/home/xxx/buildroot/output/staging/usr/include/as_devices/cpp LDFLAGS = -L/home/xxx/buildroot/output/staging/usr/lib LDFLAGS += -las_devices_cpp -las_devices EXEC_NAME = foo all: $(EXEC_NAME) $(EXEC_NAME): foo.cpp $(CXX) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ clean: rm -rf $(EXEC_NAME) rm -rf *.o .PHONY: clean
OTHER -> TODO
Development planning
AsDevices is not finished, following table indicates the remaining work:
Name | Component | C functions | C++ wrapper | Python wrapper | Python class | description |
---|---|---|---|---|---|---|
i2c | Ok | Ok | NOK | NOK | Drive I2C | |
spi | Ok, but not fully tested | Ok, but not fully tested | Ok, but not fully tested | Ok, but not fully tested | Drive SPI | |
gpio | Ok | Ok | Ok | Ok | Drive GPIO | |
ADC | max1027 | Ok for SLOW mode | Ok | NOK | NOK | |
as1531 | Ok for SLOW mode | Ok | NOK | NOK | ||
lradc | Ok for SLOW mode | Ok | NOK | NOK | ||
DAC | max5821 | OK | Ok, but not fully tested | NOK | NOK | |
mcp4912 | NOK | Ok | NOK | NOK | ||
eeprom | 93LCxx | OK | OK | NOK | NOK | |
PWM | OK | OK | NOK | NOK | ||
Backlight | OK | OK | NOK | NOK | ||
led | Ok | NOk | NOk | NOk | Drive LED |
links
- libsoc is a project similar to AsDevices.