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

Rock/wiringX

< Rock
Revision as of 03:41, 23 June 2015 by Pavle (Talk | contribs)

WiringX is a modular approach to several GPIO interfaces. Till now, it supports five platforms: Raspberry Pi, Hummingboard, BananaPi, Radxa Rock and MIPS CI20 Creator. For Radxa Rock(pro/lite), wiringX provides interfaces for GPIO, I2C, SPI and ISR. You can easily use these function on Rock through wiringX.

Firstly, get wiringX from github:

   git clone https://github.com/radxa/wiringX.git
   cd wiringX

or

   wget https://github.com/radxa/wiringX/archive/master.zip
   unzip master.zip
   cd  wiringX-master

Then, install wiringX follow the way on github.

When compile your source code, add the static lib like:

   gcc -o test test.c /usr/local/lib/libwiringX.a
   ./test

WiringX is running on your board!

Pin Number Defined in WiringX

You can find pin numbers for Radxa Rock(pro/lite) here. However, only pins can be used as GPIO are valid in wiringX. Thus, for J8, totally 21 pins can be used (number defined as 0-20) and for J12/15, 8 pins can be used (number 25-32). Besides, 3 onboard LEDs can be used, (number 33-35). Pin number defined in wiringX is as below:

Pin-wiringX.png

GPIO

WiringX provides digitalread and digitalwrite, after you set it as input/output using pinMode. The example below shows how to blink the blue LED (pin NO. 35) on board.

   #include <stdio.h>
   #include <stdlib.h>
   #include <unistd.h>
   #include "wiringX.h"
   int main(void) {
   	wiringXSetup();
   	pinMode(35, OUTPUT);
   	digitalWrite(35, HIGH);
   	sleep(1);
   	digitalWrite(35, LOW);
   	sleep(1);
   }


Theoretically, all pins can be used as GPIO. However, some multiplexed pins can't be used (pin number defined in extension header): J8: 11-16, 20, 22, 24, 26-28, 31-32; J12/15: 33-38. These pins can only be used as PWM, UART or SPI, not for GPIO.

I2C

To test I2C, SPI and ISR, an arduino uno is used. It has I2C and SPI, and can act as interrupt source.

Arduino.png

I2C0 is connected to pin 31, 32 on J8. Code on radxa:

   #include <stdio.h>                                               
   #include <stdlib.h>                                                             
   #include <unistd.h>                                                             
   #include <stdint.h>                                                             
   #include "wiringX.h"                                                            
   #define I2C_ADDR        0x04                                                    
   int fd_i2c;                                                                     
   int main(void) {                                                                
           wiringXSetup();
           if((fd_i2c = wiringXI2CSetup(I2C_ADDR)) < 0) {                          
                   fprintf(stderr, "I2C Setup failed: %i\n", fd_i2c);              
                   return -1;                                                      
           } else {                                                                
                   fprintf(stderr, "I2C Setup OK: %i\n", fd_i2c);                 
           }                                                                       
           int data=0;                                                             
           while(1) {                                                              
                   data=wiringXI2CRead(fd_i2c);                                    
                   sleep(2);                                                       
                   printf("Data received is:%d\n",data);                           
           }                                                                       
   } 

Code on arduino:

    #include <Wire.h>
    byte i=0;
    void setup()
    {
      Wire.begin(4);
      Wire.onRequest(requestEvent);
    }
    void loop()
    {
      delay(100);
    }
    void requestEvent()
    {
      Wire.write(i);
      i++;
    }

The result:

I2C.png

SPI

SPI0 and SPI1 are connected to J12/15, J8 respectively. A simple example on radxa:

   #include <stdio.h>
   #include <stdlib.h>
   #include <unistd.h>
   #include <stdint.h>
   #include "wiringX.h"
   /* SPI Config */
   #define SPI_CHAN	0
   #define SPI_SPEED	250000
   int fd_spi;
   int main(void) {
   	unsigned char spi_data=0x00;
   	wiringXSetup();
   	// set up SPI
   	if((fd_spi = wiringXSPISetup(SPI_CHAN, SPI_SPEED)) < 0) {
   		fprintf(stderr, "SPI Setup failed: %i\n", fd_spi);
   	} else {
   		fprintf(stderr, "SPI Setup OK: %i\n", fd_spi);
   	}
   	while(1) {		
   		wiringXSPIDataRW(SPI_CHAN, &spi_data, 1);
   		printf("%c\n",spi_data);
   		sleep(2);
   	}
   }

Arduino code:

   #include <SPI.h>
   char buf=0;
   volatile boolean process_it;
   void setup (void)
   {
     pinMode(MISO, OUTPUT);
     SPCR |= _BV(SPE);
     process_it = false;
     SPI.attachInterrupt();
   }
   ISR (SPI_STC_vect)
   {
     byte c = SPDR;
     SPDR=0x31;
     buf = c;
     process_it = true;
   }
   void loop (void)
   {
     if (process_it)
     {
       buf= 0;  
       process_it = false;
     } 
   }

ISR

For RK3188, Port A can be configured as interrupt. A simple example:

   #include <stdio.h>
   #include <stdlib.h>
   #include <unistd.h>
   #include <pthread.h>
   #include "wiringX.h"
   void *interrupt(void *param) {
   	while(1) {
   		if(waitForInterrupt(1, 1000) > 0) {
   			printf("interrupt\n");
   		} else {
   			printf("timeout\n");
   		}
   	}
   }
   int main(void) {
   	pthread_t pth;
   	wiringXSetup();
   	wiringXISR(1, INT_EDGE_RISING);
   	pthread_create(&pth, NULL, interrupt, NULL);
   }

It will cause interrupt when rising edge inputs to pin 1. The result:

Interrupt.png

It should take note that, for a linux kernel version below 3.12, interrupt only support INT_EDGE_RISING or INT_EDGE_FALLING, not for INT_EDGE_BOTH.

UART

We also add UART in wiringX to support serial port communication. Two UART port on J8: UART0 and UART3. A simple example to use UART0 communicate with arduino uno:

   #include <stdio.h>
   #include <stdlib.h>
   #include <unistd.h>
   #include <stdint.h>
   #include <pthread.h>
   #include "wiringX.h"
   int fd=-1, c=0;
   void *interrupt(void *param) {
   	while(1){
   		if(wiringXserialDataAvail (fd)>0){
   			c=wiringXserialGetchar(fd);
   			printf("Data received is: %d.\n", c);
   			sleep(1);
   		}
   	}
   }
   int main(void) {
   	pthread_t pth;
   	unsigned char d=0x00;
   	wiringXSetup();
   	pinMode(0, OUTPUT);
   	if ((fd = wiringXserialOpen ("/dev/ttyS0", 9600)) < 0)	{
   	    fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
   	    return -1;
   	}
   	pthread_create(&pth, NULL, interrupt, NULL);
   	wiringXserialPutchar(fd, d);
   	while(1){
   		digitalWrite(0, HIGH);
   		sleep(1);
   		digitalWrite(0, LOW);
   		sleep(1);
   	}
   }

Codes on arduino:

   boolean stringComplete = false;  // whether the string is complete
   char inChar = 0x00;
   void setup() {
     // initialize serial:
     Serial.begin(9600);
     pinMode(13,OUTPUT);
     digitalWrite(13,LOW);
   }
   void loop() {
     if (stringComplete) {
       Serial.write(inChar);
       inChar=inChar+1;
       digitalWrite(13,LOW);
       delay(1000);
       digitalWrite(13,HIGH);
       delay(1000);
     }
   }
   void serialEvent() {
     while (Serial.available()) {
       inChar = (char)Serial.read();
       if (inChar == 0x00) {
         stringComplete = true;
       }
     }
   }

Result:

Uart.png

And you can see LED on arduino and red led on Rock blink.

PWM

PWM is also added to wiringX. Interfaces are provided to use two channels pwm on the header. A simple example:

   #include <stdio.h>
   #include <stdlib.h>
   #include <unistd.h>
   #include "wiringX.h"
   int main(void) {
   	wiringXSetup();
   	pinMode(35, OUTPUT);
   	pinMode(6, PWM_OUTPUT);
   	wiringXsetPwmPeriod(6, 2000000000);
   	wiringXsetPwmDuty(6, 200000000);
   	wiringXpwmEnable(6, 1);
   	sleep(100);
   	wiringXpwmRemove(6);
   }

This will output pwm of period 2s, duty_cycle 10% on pin 12, lasts for 100s.

AIN

Three ain pins on J8. WiringX supports: int wiringXanalogRead(int channel). You can use it to read the adc value on channel 0, 1, 2.