Contents[hide] |
GPIO LIB
GPIO mean "General Purpose Input/Output" and is a special pin present in some chip that can be set as input or output and used to move a signal high or low (in output mode) or to get the signal current status (in input mode). Usually these pin are directly managed by kernel modules but there are an easy way to manage these pins also from user space.
Standard Linux kernel have inside a special interface allow to access to GPIO pins. Once executed kernel menuconfig you can easily verify is this interface is active in your kernel and, in case, enable them. The kernel tree path is the following:
Device Drivers ---> GPIO Support ---> /sys/class/gpio/... (sysfs interface)
If not, enable this feature and recompile the kernel before continue to read. The interface to allow working with GPIO is at the following filesystem path:
/sys/class/gpio/
How to know the gpio number
How to know the gpio number from the pin name? Relatively easy, look for your pin name here, and calculate the gpio number by taking into account that GPIO_BASE = 160 and NUM_GROUP = 32.
Control GPIO
By checking the schematics, it is easy to see there is a Red LED connected to GPIO1_B1 (gpio 201), but it is Control by UART2 and bootloader, you can not use it.
we use J7 Ext Port. GPIO3_D6, UART3_RTS (gpio 286).
the gpio have mux when boot.
arch\arm\mach-rk30\Iomux.c
int __init rk30_iomux_init(void)
{
int i;
printk("%s\n",__func__);
for(i=0;i<ARRAY_SIZE(rk30_muxs);i++)
{
if(rk30_muxs[i].flags != DEFAULT)
rk30_mux_set(&rk30_muxs[i]);
}
#if defined(CONFIG_UART0_RK29) || (CONFIG_RK_DEBUG_UART == 0)
rk30_mux_api_set(GPIO1A1_UART0SOUT_NAME, GPIO1A_UART0_SOUT);
rk30_mux_api_set(GPIO1A0_UART0SIN_NAME, GPIO1A_UART0_SIN);
#ifdef CONFIG_UART0_CTS_RTS_RK29
rk30_mux_api_set(GPIO1A3_UART0RTSN_NAME, GPIO1A_UART0_RTS_N);
rk30_mux_api_set(GPIO1A2_UART0CTSN_NAME, GPIO1A_UART0_CTS_N);
#endif
#endif
#if defined(CONFIG_UART1_RK29) || (CONFIG_RK_DEBUG_UART == 1)
//UART1 OR SPIM0
rk30_mux_api_set(GPIO1A5_UART1SOUT_SPI0CLK_NAME, GPIO1A_UART1_SOUT);
rk30_mux_api_set(GPIO1A4_UART1SIN_SPI0CSN0_NAME, GPIO1A_UART1_SIN);
#ifdef CONFIG_UART1_CTS_RTS_RK29
rk30_mux_api_set(GPIO1A7_UART1RTSN_SPI0TXD_NAME, GPIO1A_UART1_RTS_N);
rk30_mux_api_set(GPIO1A6_UART1CTSN_SPI0RXD_NAME, GPIO1A_UART1_CTS_N);
#endif
#endif
#if defined(CONFIG_UART2_RK29) || (CONFIG_RK_DEBUG_UART == 2)
rk30_mux_api_set(GPIO1B1_UART2SOUT_NAME, GPIO1B_UART2_SOUT);
rk30_mux_api_set(GPIO1B0_UART2SIN_NAME, GPIO1B_UART2_SIN);
#endif
#if defined(CONFIG_UART3_RK29) || (CONFIG_RK_DEBUG_UART == 3)
rk30_mux_api_set(GPIO3D4_UART3SOUT_NAME, GPIO3D_UART3_SOUT);
rk30_mux_api_set(GPIO3D3_UART3SIN_NAME, GPIO3D_UART3_SIN);
#ifdef CONFIG_UART3_CTS_RTS_RK29
rk30_mux_api_set(GPIO3D6_UART3RTSN_NAME, GPIO3D_UART3_RTS_N);
rk30_mux_api_set(GPIO3D5_UART3CTSN_NAME, GPIO3D_UART3_CTS_N);
#endif
#endif
#ifdef CONFIG_SPIM0_RK29
//UART1 OR SPIM0
rk30_mux_api_set(GPIO1A5_UART1SOUT_SPI0CLK_NAME, GPIO1A_SPI0_CLK);
rk30_mux_api_set(GPIO1A4_UART1SIN_SPI0CSN0_NAME, GPIO1A_SPI0_CSN0);
rk30_mux_api_set(GPIO1A7_UART1RTSN_SPI0TXD_NAME, GPIO1A_SPI0_TXD);
rk30_mux_api_set(GPIO1A6_UART1CTSN_SPI0RXD_NAME, GPIO1A_SPI0_RXD);
#endif
#ifdef CONFIG_SPIM1_RK29
//rk30_mux_api_set(GPIO2C7_LCDC1DATA23_SPI1CSN1_HSADCDATA4_NAME, GPIO2C_SPI1_CSN1);
rk30_mux_api_set(GPIO2C6_LCDC1DATA22_SPI1RXD_HSADCDATA3_NAME, GPIO2C_SPI1_RXD);
rk30_mux_api_set(GPIO2C5_LCDC1DATA21_SPI1TXD_HSADCDATA2_NAME, GPIO2C_SPI1_TXD);
rk30_mux_api_set(GPIO2C4_LCDC1DATA20_SPI1CSN0_HSADCDATA1_NAME, GPIO2C_SPI1_CSN0);
rk30_mux_api_set(GPIO2C3_LCDC1DATA19_SPI1CLK_HSADCDATA0_NAME, GPIO2C_SPI1_CLK);
#endif
#ifdef CONFIG_I2C0_RK30
rk30_mux_api_set(GPIO2D5_I2C0SCL_NAME, GPIO2D_I2C0_SCL);
rk30_mux_api_set(GPIO2D4_I2C0SDA_NAME, GPIO2D_I2C0_SDA);
#endif
#ifdef CONFIG_I2C1_RK30
rk30_mux_api_set(GPIO2D7_I2C1SCL_NAME, GPIO2D_I2C1_SCL);
rk30_mux_api_set(GPIO2D6_I2C1SDA_NAME, GPIO2D_I2C1_SDA);
#endif
#ifdef CONFIG_I2C2_RK30
rk30_mux_api_set(GPIO3A1_I2C2SCL_NAME, GPIO3A_I2C2_SCL);
rk30_mux_api_set(GPIO3A0_I2C2SDA_NAME, GPIO3A_I2C2_SDA);
#endif
#ifdef CONFIG_I2C3_RK30
rk30_mux_api_set(GPIO3A3_I2C3SCL_NAME, GPIO3A_I2C3_SCL);
rk30_mux_api_set(GPIO3A2_I2C3SDA_NAME, GPIO3A_I2C3_SDA);
#endif
#ifdef CONFIG_I2C4_RK30
rk30_mux_api_set(GPIO3A5_I2C4SCL_NAME, GPIO3A_I2C4_SCL);
rk30_mux_api_set(GPIO3A4_I2C4SDA_NAME, GPIO3A_I2C4_SDA);
#endif
#ifdef CONFIG_RK30_VMAC
rk30_mux_api_set(GPIO1C0_CIF1DATA2_RMIICLKOUT_RMIICLKIN_NAME, GPIO1C_RMII_CLKOUT);
rk30_mux_api_set(GPIO1C1_CIFDATA3_RMIITXEN_NAME, GPIO1C_RMII_TX_EN);
rk30_mux_api_set(GPIO1C2_CIF1DATA4_RMIITXD1_NAME, GPIO1C_RMII_TXD1);
rk30_mux_api_set(GPIO1C3_CIFDATA5_RMIITXD0_NAME, GPIO1C_RMII_TXD0);
rk30_mux_api_set(GPIO1C4_CIFDATA6_RMIIRXERR_NAME, GPIO1C_RMII_RX_ERR);
rk30_mux_api_set(GPIO1C5_CIFDATA7_RMIICRSDVALID_NAME, GPIO1C_RMII_CRS_DVALID);
rk30_mux_api_set(GPIO1C6_CIFDATA8_RMIIRXD1_NAME, GPIO1C_RMII_RXD1);
rk30_mux_api_set(GPIO1C7_CIFDATA9_RMIIRXD0_NAME, GPIO1C_RMII_RXD0);
rk30_mux_api_set(GPIO1D1_CIF1HREF_MIIMDCLK_NAME, GPIO1D_MII_MDCLK);
rk30_mux_api_set(GPIO1D0_CIF1VSYNC_MIIMD_NAME, GPIO1D_MII_MD);
#endif
#ifdef CONFIG_KP_AXP20
rk30_mux_api_set(GPIO2C7_LCDC1DATA23_SPI1CSN1_HSADCDATA4_NAME, 0);
rk30_mux_api_set(GPIO2C1_LCDC1DATA17_SMCBLSN0_HSADCDATA6_NAME, 0);
rk30_mux_api_set(GPIO2C2_LCDC1DATA18_SMCBLSN1_HSADCDATA5_NAME, 0);
rk30_mux_api_set(GPIO2C3_LCDC1DATA19_SPI1CLK_HSADCDATA0_NAME, 0);
rk30_mux_api_set(GPIO2A0_LCDC1DATA0_SMCADDR4_NAME, 0);
rk30_mux_api_set(GPIO1D2_CIF1CLKIN_NAME, 0);
rk30_mux_api_set(GPIO1D6_CIF1DATA11_NAME, 0);
rk30_mux_api_set(GPIO1D7_CIF1CLKOUT_NAME, 0);
rk30_mux_api_set(GPIO1B5_CIF0DATA1_NAME, 0);
rk30_mux_api_set(GPIO1B4_CIF0DATA0_NAME, 0);
rk30_mux_api_set(GPIO3D0_SDMMC1PWREN_NAME, 0);
#endif
return 0;
}
UART3 have Multiplexing as a UART function.
#if defined(CONFIG_UART3_RK29) || (CONFIG_RK_DEBUG_UART == 3)
rk30_mux_api_set(GPIO3D4_UART3SOUT_NAME, GPIO3D_UART3_SOUT);
rk30_mux_api_set(GPIO3D3_UART3SIN_NAME, GPIO3D_UART3_SIN);
#ifdef CONFIG_UART3_CTS_RTS_RK29
rk30_mux_api_set(GPIO3D6_UART3RTSN_NAME, GPIO3D_UART3_RTS_N);
rk30_mux_api_set(GPIO3D5_UART3CTSN_NAME, GPIO3D_UART3_CTS_N);
#endif
if you want to use UART3RTS in marsboard, you must close UART3 RTS in the kernel, when you close, UART3 RTS will become a GPIO.
disable UART3_RTS in kernel.
Device Drivers ---> Character devices ---> Serial drivers ---> RockChip RK29/RK30 serial port support ---> Serial port 3 support --->Serial port 3 CTS/RTS support
GPIO3_D6 (gpio 286) GPIO3_D5 (gpio 285), became a GPIO.
Hardware
software
In this example we will toggle the LED on and off by following these commands in a Terminal within Linux in your MarsBoard (or through ssh to the board)
#become root su root #tell Linux we want to have access to gpio pin 286 echo 286 > /sys/class/gpio/export #set it as an output pin (though we will be able to readback its value) echo "out" > /sys/class/gpio/gpio286/direction #set its value to 1 (turn off led) echo 1 > /sys/class/gpio/gpio286/value #set its value to 0 (turn on led) echo 0 > /sys/class/gpio/gpio286/value #in any case read the pin value cat /sys/class/gpio/gpio286/value
we use C Language control the GPIO.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
FILE *p=NULL;
int i=0;
printf("Hello MarsBoard User!\n");
p = fopen("/sys/class/gpio/export","w");
fprintf(p,"%d",286);
fclose(p);
p = fopen("/sys/class/gpio/gpio286/direction","w");
fprintf(p,"out");
fclose(p);
for(i=0;i<100;i++)
{
p = fopen("/sys/class/gpio/gpio286/value","w");
fprintf(p,"%d",1);
sleep(1);
fclose(p);
p = fopen("/sys/class/gpio/gpio286/value","w");
fprintf(p,"%d",0);
sleep(1);
fclose(p);
}
p = fopen("/sys/class/gpio/unexport","w");
fprintf(p,"%d",286);
fclose(p);
return 0;
}
compiled and run
gcc -o gpio gpio.c chmod 777 gpio #become root su root ./gpio