Please enable javascript, or click here to visit my ecommerce web site powered by Shopify.
Jump to: navigation, search

Difference between revisions of "WiringX"

 
(11 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
{{Languages|wiringX}}
 
{{Languages|wiringX}}
 +
 +
= wiringX =
  
 
WiringX is a GPIO library similar to wiringPi, this document describes how to build and use mraa for ROCK Pi boards.
 
WiringX is a GPIO library similar to wiringPi, this document describes how to build and use mraa for ROCK Pi boards.
 
  
 
=== List of ROCK Pi Boards supported ===
 
=== List of ROCK Pi Boards supported ===
 +
 +
* ROCK (Pi) 4A and 4B
 +
* ROCK (Pi) 4C
 +
* ROCK (Pi) 4A Plus and 4B Plus
 +
* ROCK (Pi) 4C Plus
 
* ROCK 4 SE
 
* ROCK 4 SE
* ROCK 4C Plus
+
* ROCK 3A  Hardware 1.31
* ROCK 4A/4B
+
* ROCK 3C Hardware V1.1/V1.2
* ROCK 4A/4B Plus
+
 
* ROCK 4C
+
  
 
=== List of Linux Distributions ===
 
=== List of Linux Distributions ===
 
* Ubuntu
 
* Ubuntu
 
* Debian
 
* Debian
 +
 +
  
 
=== Preparation ===
 
=== Preparation ===
Before building, please check that these tools are installed in advance
+
Essential packages include:
 +
 
 
* git
 
* git
* cmake make  
+
* cmake
 +
* make  
 
* build-essential  
 
* build-essential  
If you don't have, please install them as the following command line
 
 
  
 +
Use apt-get to get them.
  
 
<pre>
 
<pre>
rock@rockpi-4cplus:~$ sudo apt-get install cmake make build-essential -y
+
rock@rock-4c-plus:~$ sudo apt-get install -y git cmake make build-essential
 
</pre>
 
</pre>
 +
 +
  
 
=== Build wiringX with C language version ===
 
=== Build wiringX with C language version ===
 
<pre>
 
<pre>
rock@rockpi-4cplus:~$ git clone https://github.com/wiringX/wiringX.git
+
rock@rock-4c-plus:~$ git clone https://github.com/wiringX/wiringX.git
rock@rockpi-4cplus:~$ cd wiringX
+
rock@rock-4c-plus:~$ cd wiringX
rock@rockpi-4cplus:~/wiringX/$ mkdir build
+
rock@rock-4c-plus:~/wiringX/$ mkdir build
rock@rockpi-4cplus:~/wiringX/$ cd build
+
rock@rock-4c-plus:~/wiringX/$ cd build
rock@rockpi-4cplus:~/wiringX/build$ cmake ..
+
rock@rock-4c-plus:~/wiringX/build$ cmake ..
rock@rockpi-4cplus:~/wiringX/build$ make -j4
+
rock@rock-4c-plus:~/wiringX/build$ make -j4
rock@rockpi-4cplus:~/wiringX/build$ cpack -G DEB  
+
rock@rock-4c-plus:~/wiringX/build$ cpack -G DEB  
rock@rockpi-4cplus:~/wiringX/build$ sudo dpkg -i libwiringx*.deb
+
rock@rock-4c-plus:~/wiringX/build$ sudo dpkg -i libwiringx*.deb
 
</pre>
 
</pre>
  
===  Build wiringX with Python language version ===
 
Please make sure python-dev is installed before generating python version's deb of wiringx
 
  
  
 +
===  Build wiringX with Python language version ===
  
 
==== python2 version ====
 
==== python2 version ====
 +
Please make sure python-dev is installed before generating python version's deb of wiringX.
 +
 
<pre>
 
<pre>
rock@rockpi-4cplus:~$ sudo apt-get install python-dev  # for python2.x installs
+
rock@rock-4c-plus:~$ sudo apt-get install python-dev  # for python2.x
rock@rockpi-4cplus:~$ git clone https://github.com/wiringX/wiringX.git
+
rock@rock-4c-plus:~$ git clone https://github.com/wiringX/wiringX.git
rock@rockpi-4cplus:~$ cd wiringX
+
rock@rock-4c-plus:~$ cd wiringX
rock@rockpi-4cplus:~/wiringX$ cd python/
+
rock@rock-4c-plus:~/wiringX$ cd python/
rock@rockpi-4cplus:~/wiringX/python$ mkdir build
+
rock@rock-4c-plus:~/wiringX/python$ mkdir build
rock@rockpi-4cplus:~/wiringX/python/build$ cmake ..
+
rock@rock-4c-plus:~/wiringX/python/build$ cmake ..
rock@rockpi-4cplus:~/wiringX/python/build$ make -j4
+
rock@rock-4c-plus:~/wiringX/python/build$ make -j4
rock@rockpi-4cplus:~/wiringX/python/build$ cpack -G DEB  
+
rock@rock-4c-plus:~/wiringX/python/build$ cpack -G DEB  
rock@rockpi-4cplus:~/wiringX/python/build$ sudo dpkg -i python-wiringx-*.deb
+
rock@rock-4c-plus:~/wiringX/python/build$ sudo dpkg -i python-wiringx-*.deb
 
</pre>
 
</pre>
  
 
==== python3 version ====
 
==== python3 version ====
<pre>
 
rock@rockpi-4cplus:~$ sudo apt-get install python3-dev  # for python3.x installs
 
  
</pre>
 
 
 
Modify the file wiringX/python/CMakeLists.txt,
 
 
<pre>
 
<pre>
cmake_minimum_required(VERSION 2.8.8)
+
rock@rock-4c-plus:~$ git clone https://github.com/nascs/wiringX.git
 
+
rock@rock-4c-plus:~$ cd wiringX
project(wiringX C)
+
rock@rock-4c-plus:~$ git checkout -b radxa_py3.9 origin/radxa_py3.9
 
+
rock@rock-4c-plus:~/wiringX$ cd python/
set(PROJECT_VERSION 1.0)
+
rock@rock-4c-plus:~/wiringX/python$ mkdir build
set(PROJECT_NAME wiringX)
+
rock@rock-4c-plus:~/wiringX/python/build$ cmake ..
 
+
rock@rock-4c-plus:~/wiringX/python/build$ make -j4
set(CMAKE_BUILD_TYPE Release)
+
rock@rock-4c-plus:~/wiringX/python/build$ cpack -G DEB  
 
+
rock@rock-4c-plus:~/wiringX/python/build$ sudo dpkg -i python-wiringx-*.deb
find_program(PYTHON "python3")
+
 
+
set(CMAKE_SKIP_RULE_DEPENDENCY TRUE)
+
 
+
#Final compilation all platforms
+
#Removing debugging for final compilation
+
set(CMAKE_SKIP_RPATH TRUE)
+
set(CMAKE_EXE_LINKER_FLAGS " -Wl,-rpath=/usr/local/lib/,-rpath=/usr/lib/,-rpath=/lib/")
+
set(CMAKE_SHARED_LINKER_FLAGS " -Wl,-rpath=/usr/local/lib/,-rpath=/usr/lib/,-rpath=/lib/")
+
set(CMAKE_MODULE_LINKER_FLAGS " -Wl,-rpath=/usr/local/lib/,-rpath=/usr/lib/,-rpath=/lib/")
+
 
+
execute_process(COMMAND git describe --always
+
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+
RESULT_VARIABLE git_result
+
OUTPUT_VARIABLE git_ver)
+
+
# The printf is used to prevent bash naming errors e.g. libwiringx-107?-0963491.deb
+
execute_process(COMMAND git log --oneline
+
COMMAND wc -l
+
COMMAND xargs printf %d
+
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+
RESULT_VARIABLE git_result
+
OUTPUT_VARIABLE git_commits)
+
 
+
STRING(REGEX REPLACE "\n" "" git_ver "${git_ver}")
+
add_definitions(-DHASH="${git_ver}")
+
 
+
include_directories(${PROJECT_SOURCE_DIR}/src/)
+
 
+
install(
+
CODE "file(GLOB folder \"${CMAKE_BINARY_DIR}/lib.*\")"
+
CODE "file(INSTALL \${folder}/wiringX/gpio.cpython-39-aarch64-linux-gnu.so DESTINATION /usr/local/lib/python3.9/dist-packages/wiringX)"
+
CODE "file(INSTALL \${folder}/wiringX/__init__.py DESTINATION /usr/local/lib/python3.9/dist-packages/wiringX)"
+
)
+
install(FILES ${PROJECT_SOURCE_DIR}/PKG-INFO DESTINATION lib/python3.9/dist-packages/ RENAME wiringX-1.0.egg-info)
+
 
+
execute_process(COMMAND python setup.py build
+
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+
RESULT_VARIABLE python_results
+
OUTPUT_VARIABLE python_output)
+
+
set(CPACK_GENERATOR "DEB RPM")
+
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/local")
+
set(CPACK_SOURCE_STRIP_FILES TRUE)
+
set(CPACK_STRIP_FILES TRUE)
+
set(CPACK_PACKAGE_CONTACT "CurlyMo <info@pilight.org>")
+
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}-${git_commits}-g${git_ver})
+
set(CPACK_PACKAGE_NAME "python-wiringX")
+
set(CPACK_PACKAGE_FILE_NAME python-wiringx-${git_commits}-g${git_ver})
+
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
+
set(CPACK_PACKAGE_DESCRIPTION "Cross-platform GPIO Interface")
+
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Cross-platform GPIO Interface")
+
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${PROJECT_SOURCE_DIR}/res/deb/prerm;")
+
 
+
include(CPack)
+
 
</pre>
 
</pre>
 
 
 
 
 
modify the file wiringX/python/res/deb/prerm
 
<pre>
 
#!/bin/bash
 
 
if [ $1 = "purge" ] || [ $1 = "remove" ]; then
 
 
if [ -d /usr/local/lib/python3.9/dist-packages/wiringX ]; then
 
rm -r /usr/local/lib/python3.9/dist-packages/wiringX 1>/dev/null 2>/dev/null;
 
fi
 
 
if [ -f /usr/local/lib/python3.9/dist-packages/wiringX-1.0.egg-info ]; then
 
rm /usr/local/lib/python3.9/dist-packages/wiringX-1.0.egg-info 1>/dev/null 2>/dev/null;
 
fi
 
 
fi
 
</pre>
 
 
Replace the python.h header file in wiringX/python/wiringX/wiringx.c,
 
<pre>
 
#include "/usr/include/python3.9/Python.h"
 
</pre>
 
 
 
Please replace the python3.9 in the file with the python3 version on your system
 
 
<pre>
 
rock@rockpi-4cplus:~/wiringX$ cd python/
 
rock@rockpi-4cplus:~/wiringX/python$ mkdir build
 
rock@rockpi-4cplus:~/wiringX/python/build$ cmake ..
 
rock@rockpi-4cplus:~/wiringX/python/build$ make -j4
 
rock@rockpi-4cplus:~/wiringX/python/build$ cpack -G DEB
 
rock@rockpi-4cplus:~/wiringX/python/build$ sudo dpkg -i python-wiringx-*.deb
 
</pre>
 
 
 
  
  
  
 
=== C version of wiringX's core function ===
 
=== C version of wiringX's core function ===
 
+
==== general ====
 
* int wiringXSetup(char *name, void (*func)(int, char *, int, const char *, ...)); // initialize a platform with wiringX
 
* int wiringXSetup(char *name, void (*func)(int, char *, int, const char *, ...)); // initialize a platform with wiringX
  
Line 262: Line 172:
  
  
=== python language version of the function in wiringX ===
+
 
 +
=== python version of wiringX's core function ===
  
 
the following functions is similar to the C version above
 
the following functions is similar to the C version above
==== python version of wiringX's core function ====
+
 
 +
==== general ====
 
* setup(PyObject *self, PyObject *args)  
 
* setup(PyObject *self, PyObject *args)  
 
* digitalWrite(PyObject *self, PyObject *args)
 
* digitalWrite(PyObject *self, PyObject *args)
Line 272: Line 184:
 
*  validGPIO(PyObject *self, PyObject *args)
 
*  validGPIO(PyObject *self, PyObject *args)
 
==== I2C ====
 
==== I2C ====
 +
 
* setupI2C(PyObject *self, PyObject *args)
 
* setupI2C(PyObject *self, PyObject *args)
 
* I2CRead(PyObject *self, PyObject *args)
 
* I2CRead(PyObject *self, PyObject *args)
Line 286: Line 199:
  
  
 
+
=== Troubleshooting ===
 
+
===C language version of the example ===
+
===== blink =====
+
====== blink.c ======
+
 
+
<pre>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+
#include <ctype.h>
+
#include <unistd.h>
+
 
+
#include "wiringx.h"
+
 
+
char *usage =
+
"Usage: %s platform GPIO\n"
+
"      GPIO is the GPIO to write to\n"
+
"Example: %s raspberrypi2 10\n";
+
 
+
int main(int argc, char *argv[]) {
+
char *str = NULL, *platform = NULL;
+
char usagestr[130];
+
int gpio = 0, invalid = 0;
+
 
+
memset(usagestr, '\0', 130);
+
 
+
// expect only 1 argument => argc must be 2
+
if(argc != 3) {
+
snprintf(usagestr, 129, usage, argv[0], argv[0]);
+
puts(usagestr);
+
return -1;
+
}
+
 
+
// check for a valid, numeric argument
+
platform = argv[1];
+
str = argv[2];
+
while(*str != '\0') {
+
if(!isdigit(*str)) {
+
invalid = 1;
+
}
+
str++;
+
}
+
if(invalid == 1) {
+
printf("%s: Invalid GPIO %s\n", argv[0], argv[2]);
+
return -1;
+
}
+
 
+
gpio = atoi(argv[2]);
+
 
+
if(wiringXSetup(platform, NULL) == -1) {
+
wiringXGC();
+
return -1;
+
}
+
 
+
if(wiringXValidGPIO(gpio) != 0) {
+
printf("%s: Invalid GPIO %d\n", argv[0], gpio);
+
wiringXGC();
+
return -1;
+
}
+
 
+
pinMode(gpio, PINMODE_OUTPUT);
+
while(1) {
+
printf("Writing to GPIO %d: High\n", gpio);
+
digitalWrite(gpio, HIGH);
+
sleep(1);
+
printf("Writing to GPIO %d: Low\n", gpio);
+
digitalWrite(gpio, LOW);
+
sleep(1);
+
}
+
}
+
</pre>
+
use the following command line to compile it
+
<pre>
+
gcc blink.c -lwiringx -o blink
+
</pre>
+
usage:
+
<pre>
+
eg:
+
./blink rock4 13
+
</pre>
+
 
+
===== interrput =====
+
======  interrupt.c ======
+
<pre>
+
 
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+
#include <ctype.h>
+
#include <unistd.h>
+
#include <pthread.h>
+
#include <sys/syscall.h>
+
 
+
#include "wiringx.h"
+
 
+
char *usage =
+
"Usage: %s platform GPIO GPIO\n"
+
"      first GPIO to write to = output\n"
+
"      second GPIO reacts on an interrupt = input\n"
+
"Example: %s raspberrypi2 16 20\n";
+
 
+
void *interrupt(void *gpio_void_ptr) {
+
int i = 0;
+
int gpio = *(int *)gpio_void_ptr;
+
 
+
while(++i < 20) {
+
if(waitForInterrupt(gpio, 1000) > 0) {
+
printf(">>Interrupt on GPIO %d\n", gpio);
+
} else {
+
printf("  Timeout on GPIO %d\n", gpio);
+
}
+
}
+
return 0;
+
}
+
 
+
int main(int argc, char *argv[]) {
+
pthread_t pth;
+
char *str = NULL, *platform = NULL;
+
char usagestr[190];
+
int gpio_out = 0, gpio_in = 0;
+
int i = 0, err = 0, invalid = 0;
+
 
+
memset(usagestr, '\0', 190);
+
 
+
// expect 2 arguments => argc must be 3
+
if(argc != 4) {
+
snprintf(usagestr, 189, usage, argv[0], argv[0]);
+
puts(usagestr);
+
return -1;
+
}
+
 
+
// check for valid, numeric arguments
+
for(i=2; i<argc; i++) {
+
str = argv[i];
+
while(*str != '\0') {
+
if(!isdigit(*str)) {
+
invalid = 1;
+
}
+
str++;
+
}
+
if(invalid == 1) {
+
printf("%s: Invalid GPIO %s\n", argv[0], argv[i]);
+
        return -1;
+
}
+
}
+
 
+
platform = argv[1];
+
gpio_out = atoi(argv[2]);
+
gpio_in = atoi(argv[3]);
+
if(gpio_out == gpio_in) {
+
printf("%s: GPIO for output and input (interrupt) should not be the same\n", argv[0]);
+
return -1;
+
}
+
 
+
if(wiringXSetup(platform, NULL) == -1) {
+
wiringXGC();
+
return -1;
+
}
+
 
+
if(wiringXValidGPIO(gpio_out) != 0) {
+
printf("%s: Invalid GPIO %d for output\n", argv[0], gpio_out);
+
wiringXGC();
+
return -1;
+
}
+
 
+
if(wiringXValidGPIO(gpio_in) != 0) {
+
printf("%s: Invalid GPIO %d for input (interrupt)\n", argv[0], gpio_in);
+
wiringXGC();
+
return -1;
+
}
+
 
+
pinMode(gpio_out, PINMODE_OUTPUT);
+
if((wiringXISR(gpio_in, ISR_MODE_BOTH)) != 0) {
+
printf("%s: Cannot set GPIO %d to interrupt BOTH\n", argv[0], gpio_in);
+
wiringXGC();
+
return -1;
+
}
+
 
+
err = pthread_create(&pth, NULL, interrupt, &gpio_in);
+
if(err != 0) {
+
printf("Can't create thread: [%s]\n", strerror(err));
+
wiringXGC();
+
return -1;
+
} else {
+
printf("Thread created succesfully\n");
+
}
+
 
+
for(i=0; i<5; i++) {
+
printf("  Writing to GPIO %d: High\n", gpio_out);
+
digitalWrite(gpio_out, HIGH);
+
sleep(1);
+
printf("  Writing to GPIO %d: Low\n", gpio_out);
+
digitalWrite(gpio_out, LOW);
+
sleep(2);
+
}
+
 
+
printf("Main finished, waiting for thread ...\n");
+
pthread_join(pth, NULL);
+
wiringXGC();
+
 
+
return 0;
+
}
+
 
+
</pre>
+
use the following command line to compile it
+
<pre>
+
gcc interrupt.c -lwiringx -lpthread
+
</pre>
+
 
+
 
+
===== Serial =====
+
====== send.c ======
+
<pre>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <unistd.h>
+
#include <stdint.h>
+
#include <pthread.h>
+
 
+
#include "wiringx.h"
+
 
+
int main(void) {
+
 
+
struct wiringXSerial_t wiringXSerial = {115200, 7, 'o', 2, 'x'};
+
unsigned char data_send = 's';
+
int fd = -1;
+
 
+
if(wiringXSetup("rock4", NULL) == -1) {
+
wiringXGC();
+
return -1;
+
}
+
 
+
if((fd = wiringXSerialOpen("/dev/ttyS2", wiringXSerial)) < 0) {
+
fprintf(stderr, "Unable to open serial device: %s\n", strerror(errno));
+
wiringXGC();
+
return -1;
+
}
+
 
+
wiringXSerialPutChar(fd, data_send);
+
 
+
}
+
</pre>
+
use the following command line to compile it
+
<pre>
+
gcc send.c -lwiringx -o send
+
</pre>
+
 
+
 
+
======  receive.c ======
+
<pre>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <unistd.h>
+
#include <stdint.h>
+
#include <pthread.h>
+
 
+
#include "wiringx.h"
+
 
+
int main(void) {
+
 
+
struct wiringXSerial_t wiringXSerial = {115200, 7, 'o', 2, 'x'};
+
int fd = -1;
+
int date_receive = 0;
+
 
+
if(wiringXSetup("rock4", NULL) == -1) {
+
wiringXGC();
+
return -1;
+
}
+
 
+
if((fd = wiringXSerialOpen("/dev/ttyS2", wiringXSerial)) < 0) {
+
fprintf(stderr, "Unable to open serial device: %s\n", strerror(errno));
+
wiringXGC();
+
return -1;
+
}
+
 
+
while(1) {
+
if(wiringXSerialDataAvail(fd) > 0) {
+
date_receive = wiringXSerialGetChar(fd);
+
printf("Data received is: %c.\n", date_receive);
+
}
+
}
+
}
+
 
+
</pre>
+
use the following command line to compile it
+
<pre>
+
gcc receive.c -lwiringx  -o receive
+
</pre>
+
 
+
 
+
===== I2C =====
+
====== i2c_test.c ======
+
<pre>
+
#include <stdio.h>
+
#include "wiringx.h"
+
#include <unistd.h>
+
 
+
int main() {
+
 
+
    int fd ;
+
   
+
    if(wiringXSetup("rock4", NULL) == -1) {
+
        printf("wiringXSetup failed ...\n");
+
        return -1;
+
    }
+
    if((fd = wiringXI2CSetup("/dev/i2c-7",0x20)) == -1) {
+
        printf("wiringXI2CSetup failed ...\n");
+
        return -1;
+
    }
+
   
+
    while(1) {
+
        wiringXI2CWrite(fd,0x5f);
+
        sleep(1);
+
        wiringXI2CWrite(fd,0x7f);
+
        sleep(1);
+
    }
+
 
+
 
+
    return 0;
+
}
+
</pre>
+
 
+
use the following command line to compile it
+
<pre>
+
gcc i2c_test.c -lwiringx
+
</pre>
+
 
+
 
+
===== SPI =====
+
====== spi_test.c ======
+
<pre>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <unistd.h>
+
#include <stdint.h>
+
#include <string.h>
+
#include <errno.h>
+
 
+
#include "wiringx.h"
+
 
+
#define TRUE (1==1)
+
#define FALSE (!TRUE)
+
 
+
#define SPI_CHAN 0
+
#define NUM_TIMES 100
+
#define MAX_SIZE (1024*1024)
+
 
+
static int myFd ;
+
 
+
 
+
void spiSetup (int speed)
+
{
+
  if ((myFd = wiringXSPISetup (SPI_CHAN, speed)) < 0)
+
  {
+
    fprintf (stderr, "Can't open the SPI bus: %s\n", strerror (errno)) ;
+
    exit (EXIT_FAILURE) ;
+
  }
+
}
+
 
+
 
+
int main (void)
+
{
+
  int speed, times, size ;
+
  unsigned int start, end ;
+
  int spiFail ;
+
  unsigned char *myData ;
+
  double timePerTransaction, perfectTimePerTransaction, dataSpeed ;
+
 
+
  if ((myData = malloc (MAX_SIZE)) == NULL)
+
  {
+
    fprintf (stderr, "Unable to allocate buffer: %s\n", strerror (errno)) ;
+
    exit (EXIT_FAILURE) ;
+
  }
+
 
+
  if(wiringXSetup("radxa_e23", NULL) == -1) {
+
  wiringXGC();
+
return -1;
+
  }
+
 
+
  for (speed = 1 ; speed <= 32 ; speed *= 2)
+
  {
+
    printf ("+-------+--------+----------+----------+-----------+------------+\n") ;
+
    printf ("|  MHz |  Size | mS/Trans |      TpS |    Mb/Sec | Latency mS |\n") ;
+
    printf ("+-------+--------+----------+----------+-----------+------------+\n") ;
+
 
+
    spiFail = FALSE ;
+
    spiSetup (speed * 1000000) ;
+
    for (size = 1 ; size <= MAX_SIZE ; size *= 2)
+
    {
+
      printf ("| %5d | %6d ", speed, size) ;
+
 
+
      start = usleep(500);
+
      for (times = 0 ; times < NUM_TIMES ; ++times)
+
if (wiringXSPIDataRW (SPI_CHAN, myData, size) == -1)
+
{
+
  printf ("SPI failure: %s\n", strerror (errno)) ;
+
  spiFail = TRUE ;
+
  break ;
+
}
+
      end = usleep(500);
+
 
+
      if (spiFail)
+
break ;
+
 
+
      timePerTransaction        = ((double)(end - start) / (double)NUM_TIMES) / 1000.0 ;
+
      dataSpeed                =  (double)(size * 8)    / (1024.0 * 1024.0) / timePerTransaction  ;
+
      perfectTimePerTransaction = ((double)(size * 8))  / ((double)(speed * 1000000)) ;
+
 
+
      printf ("| %8.3f ", timePerTransaction * 1000.0) ;
+
      printf ("| %8.1f ", 1.0 / timePerTransaction) ;
+
      printf ("| %9.5f ", dataSpeed) ;
+
      printf ("|  %8.5f ", (timePerTransaction - perfectTimePerTransaction) * 1000.0) ;
+
      printf ("|\n") ;
+
 
+
    }
+
 
+
    close (myFd) ;
+
    printf ("+-------+--------+----------+----------+-----------+------------+\n") ;
+
    printf ("\n") ;
+
  }
+
 
+
  return 0 ;
+
}
+
 
+
</pre>
+
 
+
use the following command line to compile it
+
<pre>
+
gcc spi_test.c -lwiringx
+
</pre>
+
 
+
 
+
==== Python language version of the example ====
+
===== blink.py =====
+
<pre>
+
import os
+
import sys
+
from time import sleep
+
from wiringX import gpio
+
 
+
gpio.setup(gpio.ROCK4);
+
 
+
gpio.pinMode(gpio.PIN0, gpio.PINMODE_OUTPUT);
+
 
+
try:
+
while True:
+
gpio.digitalWrite(gpio.PIN0, gpio.HIGH);
+
sleep(1);
+
gpio.digitalWrite(gpio.PIN0, gpio.LOW);
+
sleep(1);
+
except KeyboardInterrupt:
+
pass
+
 
+
</pre>
+
Run the program from the following command line
+
<pre>
+
sudo python blink.py
+
</pre>
+
or
+
<pre>
+
sudo python3 blink.py
+
</pre>
+
 
+
+
===== interrupt.py =====
+
<pre>
+
import os
+
import sys
+
from time import sleep
+
from wiringX.gpio import gpio
+
 
+
def interrupt(x):
+
if x > 0:
+
print "interrupt"
+
else:
+
print "timeout"
+
 
+
gpio.setup(gpio.ROCK4);
+
 
+
gpio.pinMode(gpio.PIN0, gpio.PINMODE_OUTPUT);
+
gpio.wiringXISR(gpio.PIN1, gpio.ISR_EDGE_BOTH);
+
 
+
try:
+
gpio.waitForInterrupt(interrupt, gpio.PIN1, 1000);
+
while True:
+
gpio.digitalWrite(gpio.PIN0, gpio.HIGH);
+
sleep(1);
+
gpio.digitalWrite(gpio.PIN0, gpio.LOW);
+
sleep(2);
+
except KeyboardInterrupt:
+
pass;
+
 
+
</pre>
+
Run the program from the following command line
+
<pre>
+
sudo python interrupt.py
+
</pre>
+
or
+
<pre>
+
sudo python3 interrupt.py
+
</pre>
+
 
+
===== I2C =====
+
====== i2c-test.py ======
+
<pre>
+
from time import sleep
+
 
+
from wiringX import gpio
+
 
+
# setup wiringX
+
gpio.setup(gpio.ROCK4)
+
 
+
# get a handle to the sensor, using the default I2C address
+
fd = gpio.I2CSetup("/dev/i2c-0", 0x48)
+
while True:
+
    # read from the default register
+
    data = gpio.I2CReadReg16(fd, 0x00)
+
    reg = []
+
    # calculate the temperature
+
    reg.append((data>>8)&0xff)
+
    reg.append(data&0xff)
+
    res  = (reg[1] << 4) | (reg[0] >> 4)
+
    res = res * 0.0625
+
 
+
    # print the result
+
    print(u'Temperature: ' + str(res) + u' C')
+
    sleep(1)
+
 
+
</pre>
+
 
+
Run the program from the following command line
+
<pre>
+
sudo python i2c-test.py
+
</pre>
+
or
+
<pre>
+
sudo python3 i2c-test.py
+
</pre>
+
 
+
===== SPI =====
+
====== spi-test.py ======
+
<pre>
+
from time import sleep
+
 
+
from wiringX import gpio
+
 
+
# setup wiringX
+
gpio.setup(gpio.RASPBERRYPI1B2)
+
 
+
# set up the SPI device
+
fd = gpio.SPISetup(0, 250000)
+
 
+
while True:
+
    # write 1 2 3 4 to the display
+
    data = gpio.SPIDataRW(0, bytearray([0x01,0x02,0x03,0x04]), 4)
+
 
+
    # set the decimal point to position 2
+
    data = gpio.SPIDataRW(0, bytearray([0x77,0x02]), 2)
+
    sleep(1)
+
 
+
    # clear the display
+
    data = gpio.SPIDataRW(0, bytearray([0x76]), 1)
+
    sleep(1)
+
 
+
</pre>
+
Run the program from the following command line
+
<pre>
+
sudo python spi-test.py
+
</pre>
+
or
+
<pre>
+
sudo python3 spi-test.py
+
</pre>
+
 
+
 
+
 
+
==== Troubleshooting ====
+
 
* If you have an issue, start a new post on the forum. https://forum.radxa.com/.
 
* If you have an issue, start a new post on the forum. https://forum.radxa.com/.

Latest revision as of 07:18, 1 March 2023

wiringX

WiringX is a GPIO library similar to wiringPi, this document describes how to build and use mraa for ROCK Pi boards.

List of ROCK Pi Boards supported

  • ROCK (Pi) 4A and 4B
  • ROCK (Pi) 4C
  • ROCK (Pi) 4A Plus and 4B Plus
  • ROCK (Pi) 4C Plus
  • ROCK 4 SE
  • ROCK 3A Hardware 1.31
  • ROCK 3C Hardware V1.1/V1.2


List of Linux Distributions

  • Ubuntu
  • Debian


Preparation

Essential packages include:

  • git
  • cmake
  • make
  • build-essential

Use apt-get to get them.

rock@rock-4c-plus:~$ sudo apt-get install -y git cmake make build-essential


Build wiringX with C language version

rock@rock-4c-plus:~$ git clone https://github.com/wiringX/wiringX.git
rock@rock-4c-plus:~$ cd wiringX
rock@rock-4c-plus:~/wiringX/$ mkdir build
rock@rock-4c-plus:~/wiringX/$ cd build
rock@rock-4c-plus:~/wiringX/build$ cmake ..
rock@rock-4c-plus:~/wiringX/build$ make -j4
rock@rock-4c-plus:~/wiringX/build$ cpack -G DEB 
rock@rock-4c-plus:~/wiringX/build$ sudo dpkg -i libwiringx*.deb


Build wiringX with Python language version

python2 version

Please make sure python-dev is installed before generating python version's deb of wiringX.

rock@rock-4c-plus:~$ sudo apt-get install python-dev   # for python2.x
rock@rock-4c-plus:~$ git clone https://github.com/wiringX/wiringX.git
rock@rock-4c-plus:~$ cd wiringX
rock@rock-4c-plus:~/wiringX$ cd python/
rock@rock-4c-plus:~/wiringX/python$ mkdir build
rock@rock-4c-plus:~/wiringX/python/build$ cmake ..
rock@rock-4c-plus:~/wiringX/python/build$ make -j4
rock@rock-4c-plus:~/wiringX/python/build$ cpack -G DEB 
rock@rock-4c-plus:~/wiringX/python/build$ sudo dpkg -i python-wiringx-*.deb

python3 version

rock@rock-4c-plus:~$ git clone https://github.com/nascs/wiringX.git 
rock@rock-4c-plus:~$ cd wiringX
rock@rock-4c-plus:~$ git checkout -b radxa_py3.9 origin/radxa_py3.9
rock@rock-4c-plus:~/wiringX$ cd python/
rock@rock-4c-plus:~/wiringX/python$ mkdir build
rock@rock-4c-plus:~/wiringX/python/build$ cmake ..
rock@rock-4c-plus:~/wiringX/python/build$ make -j4
rock@rock-4c-plus:~/wiringX/python/build$ cpack -G DEB 
rock@rock-4c-plus:~/wiringX/python/build$ sudo dpkg -i python-wiringx-*.deb


C version of wiringX's core function

general

  • int wiringXSetup(char *name, void (*func)(int, char *, int, const char *, ...)); // initialize a platform with wiringX
  • int pinMode(int pin, enum pinmode_t mode); // set the operating mode of the pin
mode:
       PINMODE_NOT_SET
       PINMODE_INPUT
       PINMODE_OUTPUT
       PINMODE_INTERRUPT  
  • int digitalWrite(int pin, enum digital_value_t value); // write a digital_value to the pin
value:
       LOW,
       HIGH
  • int digitalRead(int pin) // read value of the pin
  • int wiringXISR(int pin, enum isr_mode_t mode); // uses a function as an argument to get an interrupt in a particular GPIO pin
mode: 
       ISR_MODE_UNKNOWN 
       ISR_MODE_RISING 
       ISR_MODE_FALLING 
       ISR_MODE_BOTH 
       ISR_MODE_NONE 
  • int waitForInterrupt(int pin, int ms); // this is the wait event interrupt function,
  • int wiringXValidGPIO(int pin); // check that the pin is valid

I2C

  • int wiringXI2CSetup(const char *path, int devId) // this function initializes the I2C system with the specified Acura symbol
  • int wiringXI2CRead(int fd); // simple device read operation. Some Actos can be read directly without the need to send any register addresses
  • int wiringXI2CReadReg8(int fd, int reg); // An 8-bit value can be read from a specified device register
  • int wiringXI2CReadReg16(int fd, int reg); // An 16-bit value can be read from a specified device register
  • int wiringXI2CWrite(int fd, int data); // simple device write operations. Some devices can accept data without sending any internal register addresses
  • int wiringXI2CWriteReg8(int fd, int reg, int data); // An 8-bit value can be written to the specified Acura register
  • int wiringXI2CWriteReg8(int fd, int reg, int data); // An 16-bit value can be written to the specified Acura register

SPI

  • int wiringXSPISetup(int channel, int speed); // use this function to initialize an SPI channel
  • int wiringXSPIDataRW(int channel, unsigned char *data, int len); // This function performs a simultaneous read and write operation through the selected SPI bus. The data in the buffer, will be covered with Hang SPI bus back to the data. For simple read and write operations, you can use standard system functions: read() and write()

Serial

  • int wiringXSerialOpen(const char *device, struct wiringXSerial_t wiringXSerial); // this function will open the serial port device initially and set the baud rate of communication

typedef struct wiringXSerial_t {
	unsigned int baud;
	unsigned int databits;
	unsigned int parity;
	unsigned int stopbits;
	unsigned int flowcontrol;
} wiringXSerial_t;


  • void wiringXSerialClose(int fd); // shut down the device with the specified file descriptor
  • void wiringXSerialFlush(int fd); // discard all received data or wait for writing to complete on the specified device
  • void wiringXSerialPutChar(int fd, unsigned char c); // writes a single byte to the file descriptor of the specified device
  • void wiringXSerialPuts(int fd, const char *s); // this function writes a string ending in 0 to the file descriptor of the specified device
  • void wiringXSerialPrintf(int fd, const char *message, ...); // used the same way as printf
  • int wiringXSerialDataAvail(int fd); // returns the number of bytes available in the serial port receive cache
  • int wiringXSerialGetChar(int fd); // returns the next character to be read for the serial port device. If there is no data, the function will wait 10 seconds and return -1 if there is still no data after 10 seconds.


python version of wiringX's core function

the following functions is similar to the C version above

general

  • setup(PyObject *self, PyObject *args)
  • digitalWrite(PyObject *self, PyObject *args)
  • digitalRead(PyObject *self, PyObject *args)
  • pinMode(PyObject *self, PyObject *args)
  • validGPIO(PyObject *self, PyObject *args)

I2C

  • setupI2C(PyObject *self, PyObject *args)
  • I2CRead(PyObject *self, PyObject *args)
  • I2CReadReg8(PyObject *self, PyObject *args)
  • I2CReadReg16(PyObject *self, PyObject *args)
  • 2CWrite(PyObject *self, PyObject *args)
  • I2CWriteReg8(PyObject *self, PyObject *args)
  • I2CWriteReg16(PyObject *self, PyObject *args)

spi

  • SPIGetFd(PyObject *self, PyObject *args)
  • SPIDataRW(PyObject *self, PyObject *args)
  • setupSPI(PyObject *self, PyObject *args)


Troubleshooting