Skip to content

Commit a95431e

Browse files
committed
Initial Release
Basic GPIO functions
1 parent 5d25a48 commit a95431e

File tree

9 files changed

+1122
-0
lines changed

9 files changed

+1122
-0
lines changed

OPi/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
__author__ = 'Jeremie-C'

setup.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""
2+
Copyright (c) 2012-2016 Ben Croston
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
this software and associated documentation files (the "Software"), to deal in
6+
the Software without restriction, including without limitation the rights to
7+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8+
of the Software, and to permit persons to whom the Software is furnished to do
9+
so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all
12+
copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
SOFTWARE.
21+
"""
22+
23+
from distutils.core import setup, Extension
24+
25+
classifiers = ['Development Status :: 3 - Alpha',
26+
'Operating System :: POSIX :: Linux',
27+
'License :: OSI Approved :: MIT License',
28+
'Intended Audience :: Developers',
29+
'Programming Language :: Python :: 2.6',
30+
'Programming Language :: Python :: 2.7',
31+
'Programming Language :: Python :: 3',
32+
'Topic :: Software Development',
33+
'Topic :: Home Automation',
34+
'Topic :: System :: Hardware']
35+
36+
setup(name = 'OPi.GPIO',
37+
version = '0.6.3',
38+
author = 'Jeremie-C',
39+
description = 'A module to control OrangePi GPIO channels',
40+
license = 'MIT',
41+
keywords = 'OrangePi GPIO',
42+
url = 'https://github.com/Jeremie-C/OrangePi.GPIO',
43+
classifiers = classifiers,
44+
packages = ['OPi'],
45+
ext_modules = [Extension('OPi.GPIO', ['source/py_gpio.c', 'source/c_gpio.c', 'source/common.c', 'source/constants.c'])])

source/c_gpio.c

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
/*
2+
Copyright (c) 2012-2015 Ben Croston
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
this software and associated documentation files (the "Software"), to deal in
6+
the Software without restriction, including without limitation the rights to
7+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8+
of the Software, and to permit persons to whom the Software is furnished to do
9+
so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all
12+
copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
SOFTWARE.
21+
*/
22+
23+
#include <stdint.h>
24+
#include <stdlib.h>
25+
#include <stdio.h>
26+
#include <fcntl.h>
27+
#include <sys/mman.h>
28+
#include "c_gpio.h"
29+
30+
static volatile uint32_t *gpio_map;
31+
32+
uint32_t readl(uint32_t addr)
33+
{
34+
uint32_t val = 0;
35+
uint32_t mmap_base = (addr & ~MAP_MASK);
36+
uint32_t mmap_seek = ((addr - mmap_base) >> 2);
37+
val = *(gpio_map + mmap_seek);
38+
if(OPiGPIODebug)
39+
printf("mmap_base = 0x%x\t mmap_seek = 0x%x\t gpio_map = 0x%x\t total = 0x%x\n",mmap_base,mmap_seek,gpio_map,(gpio_map + mmap_seek));
40+
41+
return val;
42+
}
43+
44+
void writel(uint32_t val, uint32_t addr)
45+
{
46+
uint32_t mmap_base = (addr & ~MAP_MASK);
47+
uint32_t mmap_seek = ((addr - mmap_base) >> 2);
48+
*(gpio_map + mmap_seek) = val;
49+
}
50+
51+
int setup(void)
52+
{
53+
int mem_fd;
54+
uint8_t *gpio_mem;
55+
56+
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0)
57+
{
58+
return SETUP_DEVMEM_FAIL;
59+
}
60+
61+
if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
62+
return SETUP_MALLOC_FAIL;
63+
64+
if ((uint32_t)gpio_mem % PAGE_SIZE)
65+
gpio_mem += PAGE_SIZE - ((uint32_t)gpio_mem % PAGE_SIZE);
66+
67+
gpio_map = (uint32_t *)mmap( (caddr_t)gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, GPIO_BASE_OPI);
68+
69+
if(OPiGPIODebug)
70+
printf("gpio_mem = 0x%x\t gpio_map = 0x%x\n",gpio_mem,gpio_map);
71+
72+
if ((uint32_t)gpio_map < 0)
73+
return SETUP_MMAP_FAIL;
74+
75+
return SETUP_OK;
76+
}
77+
78+
int gpio_function(int gpio)
79+
{
80+
uint32_t regval = 0;
81+
int bank = gpio >> 5;
82+
int index = gpio - (bank << 5);
83+
int offset = ((index - ((index >> 3) << 3)) << 2);
84+
uint32_t phyaddr = SUNXI_GPIO_BASE + (bank * 36) + ((index >> 3) << 2);
85+
86+
regval = readl(phyaddr);
87+
if (OPiGPIODebug)
88+
printf("read reg val: 0x%x offset:%d\n",regval,offset);
89+
90+
regval >>= offset;
91+
regval &= 7;
92+
if (OPiGPIODebug)
93+
printf("read reg val: 0x%x\n",regval);
94+
95+
return regval; // 1=input, 0=output, 4=alt0
96+
}
97+
98+
void set_pullupdn(int gpio, int pud)//void sunxi_pullUpDnControl (int pin, int pud)
99+
{
100+
uint32_t regval = 0;
101+
int bank = gpio >> 5;
102+
int index = gpio - (bank << 5);
103+
int sub = index >> 4;
104+
int sub_index = index - 16*sub;
105+
uint32_t phyaddr = SUNXI_GPIO_BASE + (bank * 36) + 0x1C + 4*sub; // +0x1c -> pullUpDn reg
106+
107+
if (OPiGPIODebug)
108+
printf("func:%s pin:%d,bank:%d index:%d sub:%d phyaddr:0x%x\n",__func__, gpio,bank,index,sub,phyaddr);
109+
110+
regval = readl(phyaddr);
111+
if (OPiGPIODebug)
112+
printf("pullUpDn reg:0x%x, pud:0x%x sub_index:%d\n", regval, pud, sub_index);
113+
regval &= ~(3 << (sub_index << 1));
114+
regval |= (pud << (sub_index << 1));
115+
if (OPiGPIODebug)
116+
printf("pullUpDn val ready to set:0x%x\n", regval);
117+
writel(regval, phyaddr);
118+
regval = readl(phyaddr);
119+
if (OPiGPIODebug)
120+
printf("pullUpDn reg after set:0x%x addr:0x%x\n", regval, phyaddr);
121+
}
122+
123+
void setup_gpio(int gpio, int direction, int pud)//void sunxi_set_gpio_mode(int pin,int mode)
124+
{
125+
uint32_t regval = 0;
126+
int bank = gpio >> 5;
127+
int index = gpio - (bank << 5);
128+
int offset = ((index - ((index >> 3) << 3)) << 2);
129+
uint32_t phyaddr = SUNXI_GPIO_BASE + (bank * 36) + ((index >> 3) << 2);
130+
if (OPiGPIODebug)
131+
printf("func:%s pin:%d, direction:%d bank:%d index:%d phyaddr:0x%x\n",__func__, gpio , direction,bank,index,phyaddr);
132+
133+
regval = readl(phyaddr);
134+
if (OPiGPIODebug)
135+
printf("read reg val: 0x%x offset:%d\n",regval,offset);
136+
137+
set_pullupdn(gpio, pud);
138+
139+
if(INPUT == direction)
140+
{
141+
regval &= ~(7 << offset);
142+
writel(regval, phyaddr);
143+
regval = readl(phyaddr);
144+
if (OPiGPIODebug)
145+
printf("Input mode set over reg val: 0x%x\n",regval);
146+
}
147+
else if(OUTPUT == direction)
148+
{
149+
regval &= ~(7 << offset);
150+
regval |= (1 << offset);
151+
if (OPiGPIODebug)
152+
printf("Out mode ready set val: 0x%x\n",regval);
153+
writel(regval, phyaddr);
154+
regval = readl(phyaddr);
155+
if (OPiGPIODebug)
156+
printf("Out mode set over reg val: 0x%x\n",regval);
157+
}
158+
else
159+
{
160+
printf("line:%dpin number error\n",__LINE__);
161+
}
162+
}
163+
164+
void output_gpio(int gpio, int value) //void sunxi_digitalWrite(int pin, int value)
165+
{
166+
uint32_t regval = 0;
167+
int bank = gpio >> 5;
168+
int index = gpio - (bank << 5);
169+
uint32_t phyaddr = SUNXI_GPIO_BASE + (bank * 36) + 0x10; // +0x10 -> data reg
170+
if (OPiGPIODebug)
171+
printf("func:%s pin:%d, value:%d bank:%d index:%d phyaddr:0x%x\n",__func__, gpio , value,bank,index,phyaddr);
172+
173+
regval = readl(phyaddr);
174+
if (OPiGPIODebug)
175+
printf("before write reg val: 0x%x,index:%d\n",regval,index);
176+
if(0 == value)
177+
{
178+
regval &= ~(1 << index);
179+
writel(regval, phyaddr);
180+
regval = readl(phyaddr);
181+
if (OPiGPIODebug)
182+
printf("LOW val set over reg val: 0x%x\n",regval);
183+
}
184+
else
185+
{
186+
regval |= (1 << index);
187+
writel(regval, phyaddr);
188+
regval = readl(phyaddr);
189+
if (OPiGPIODebug)
190+
printf("HIGH val set over reg val: 0x%x\n",regval);
191+
}
192+
}
193+
194+
int input_gpio(int gpio)//int sunxi_digitalRead(int pin)
195+
{
196+
uint32_t regval = 0;
197+
int bank = gpio >> 5;
198+
int index = gpio - (bank << 5);
199+
uint32_t phyaddr = SUNXI_GPIO_BASE + (bank * 36) + 0x10; // +0x10 -> data reg
200+
if (OPiGPIODebug)
201+
printf("func:%s pin:%d,bank:%d index:%d phyaddr:0x%x\n",__func__, gpio,bank,index,phyaddr);
202+
203+
regval = readl(phyaddr);
204+
regval = regval >> index;
205+
regval &= 1;
206+
if (OPiGPIODebug)
207+
printf("***** read reg val: 0x%x,bank:%d,index:%d,line:%d\n",regval,bank,index,__LINE__);
208+
209+
return regval;
210+
}
211+
212+
void clear_event_detect(int gpio)
213+
{
214+
return;
215+
}
216+
217+
int eventdetected(int gpio)
218+
{
219+
return 0;
220+
}
221+
222+
void set_rising_event(int gpio, int enable)
223+
{
224+
return;
225+
}
226+
227+
void set_falling_event(int gpio, int enable)
228+
{
229+
return;
230+
}
231+
232+
void set_high_event(int gpio, int enable)
233+
{
234+
return;
235+
}
236+
237+
void set_low_event(int gpio, int enable)
238+
{
239+
return;
240+
}
241+
242+
void cleanup(void)
243+
{
244+
munmap((caddr_t)gpio_map, BLOCK_SIZE);
245+
}

source/c_gpio.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
Copyright (c) 2012-2015 Ben Croston
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
this software and associated documentation files (the "Software"), to deal in
6+
the Software without restriction, including without limitation the rights to
7+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8+
of the Software, and to permit persons to whom the Software is furnished to do
9+
so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all
12+
copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
SOFTWARE.
21+
*/
22+
23+
#define GPIO_BASE_OPI (0x01C20000)
24+
#define SUNXI_GPIO_BASE (0x01C20800)
25+
26+
#define PAGE_SIZE (4*1024)
27+
#define BLOCK_SIZE (4*1024)
28+
#define MAP_SIZE (4096*2)
29+
#define MAP_MASK (MAP_SIZE - 1)
30+
31+
#define SETUP_OK 0
32+
#define SETUP_DEVMEM_FAIL 1
33+
#define SETUP_MALLOC_FAIL 2
34+
#define SETUP_MMAP_FAIL 3
35+
36+
#define INPUT 1 // is really 0 for control register!
37+
#define OUTPUT 0 // is really 1 for control register!
38+
39+
#define HIGH 1
40+
#define LOW 0
41+
42+
#define PUD_OFF 0
43+
#define PUD_DOWN 2
44+
#define PUD_UP 1
45+
46+
#define OPiGPIODebug 0
47+
48+
int setup(void);
49+
int gpio_function(int gpio);
50+
void setup_gpio(int gpio, int direction, int pud);
51+
void output_gpio(int gpio, int value);
52+
int input_gpio(int gpio);
53+
void clear_event_detect(int gpio);
54+
int eventdetected(int gpio);
55+
void set_rising_event(int gpio, int enable);
56+
void set_falling_event(int gpio, int enable);
57+
void set_high_event(int gpio, int enable);
58+
void set_low_event(int gpio, int enable);
59+
void cleanup(void);

0 commit comments

Comments
 (0)