1: /*************************************************************************
2: * (C) 2011 AITNET - Sofia/Bulgaria - <office@aitbg.com>
3: * by Michael Pounov <misho@aitbg.com>
4: *
5: * $Author: misho $
6: * $Id: pceng_run.c,v 1.1.2.9 2011/10/24 23:14:36 misho Exp $
7: *
8: *************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
46: #include "global.h"
47: #include "pceng.h"
48:
49:
50: const u_int led_base[2][MAX_GPIO_PINS] = {{0xf410, 0xf400, 0xf400, 0xf400},
51: {0x61b0, 0x6100, 0x6180, 0x6180}};
52: const int led_bit[2][MAX_GPIO_PINS] = {{8, 2, 3, 18}, {8, 6, 9, 11}};
53: const int gpio_off[2] = { 0x4, 0x10 };
54:
55:
56: static inline board_t
57: getBoard()
58: {
59: board_t type;
60: char szStr[STRSIZ];
61:
62: FTRACE(3);
63:
64: cfg_LoadAttribute(&cfg, CFG("pceng"), CFG("board"), CFG(szStr), sizeof szStr, DEFAULT_BOARD);
65: if (!strcasecmp(szStr, "alix"))
66: type = alix;
67: else if (!strcasecmp(szStr, "wrap"))
68: type = wrap;
69: else {
70: type = unknown;
71: syslog(LOG_ERR, "Error:: unknown board type %s", szStr);
72: }
73:
74: return type;
75: }
76:
77: static u_int
78: gpioRead(u_char ledno)
79: {
80: u_int n;
81: board_t type = getBoard();
82:
83: FTRACE(3);
84:
85: switch (type) {
86: case wrap:
87: n = inl(led_base[type - 1][ledno] + gpio_off[type - 1]);
88: if (n & (1 << led_bit[type - 1][ledno]))
89: n = 1;
90: else
91: n = 0;
92: break;
93: case alix:
94: n = inl(led_base[type - 1][ledno]);
95: if (n & (1 << led_bit[type - 1][ledno]))
96: n = 0;
97: else
98: n = 1;
99: break;
100: default:
101: return -1;
102: }
103:
104: return n;
105: }
106:
107:
108: int
109: LED(u_char ledno, u_char state)
110: {
111: u_int n;
112: board_t type = getBoard();
113:
114: FTRACE(3);
115:
116: switch (type) {
117: case wrap:
118: n = inl(led_base[type - 1][ledno]);
119: /* read */
120: if (state == (u_char) -1)
121: return (n &= (1 << led_bit[type - 1][ledno]));
122:
123: if (state)
124: n |= (1 << led_bit[type - 1][ledno]);
125: else
126: n &= ~(1 << led_bit[type - 1][ledno]);
127: break;
128: case alix:
129: /* read */
130: if (state == (u_char) -1) {
131: n = inl(led_base[type - 1][ledno]);
132: return !(n &= (1 << led_bit[type - 1][ledno]));
133: }
134:
135: if (state)
136: n = (1 << (led_bit[type - 1][ledno] + gpio_off[type - 1]));
137: else
138: n = (1 << led_bit[type - 1][ledno]);
139: break;
140: default: /* unknown */
141: return -1;
142: }
143:
144: outl(led_base[type - 1][ledno], n);
145: return (int) state;
146: }
147:
148: static int
149: RunCmd(u_char pin, u_int state)
150: {
151: char szStr[STRSIZ], szArg[STRSIZ] = { 0 };
152:
153: FTRACE(3);
154:
155: switch (pin) {
156: case 0: /* button */
157: cfg_LoadAttribute(&cfg, CFG("event"), CFG("button_exec"),
158: CFG(szStr), sizeof szStr, NULL);
159: break;
160: case 1: /* LEDs */
161: case 2:
162: case 3:
163: cfg_LoadAttribute(&cfg, CFG("event"), CFG("led_exec"),
164: CFG(szStr), sizeof szStr, NULL);
165: break;
166: }
167: if (!*szStr)
168: return 0;
169: if (pin)
170: snprintf(szArg, sizeof szArg, "%d=%d", pin, state);
171: else
172: snprintf(szArg, sizeof szArg, "%d", state);
173:
174: switch (fork()) {
175: case -1:
176: syslog(LOG_ERR, "Error:: RunCmd #%d - %s\n", errno, strerror(errno));
177: return -1;
178: case 0: /* execute command */
179: return execl(szStr, szStr, szArg, NULL);
180: }
181:
182: return 0;
183: }
184:
185: int
186: Run()
187: {
188: register u_char i;
189: u_int ret, t, slice, states = 0;
190: char szStr[STRSIZ];
191:
192: FTRACE(3);
193:
194: /* init array */
195: for (i = 0; i < MAX_GPIO_PINS; i++)
196: if ((ret = gpioRead(i)) == -1)
197: return 126;
198: else
199: states |= ret ? (1 << i) : 0;
200:
201: /* state machine */
202: while (!Kill) {
203: cfg_LoadAttribute(&cfg, CFG("event"), CFG("button_slice"),
204: CFG(szStr), sizeof szStr, DEFAULT_SLICE);
205: slice = strtol(szStr, NULL, 0);
206: if (!slice)
207: slice = strtol(DEFAULT_SLICE, NULL, 0);
208: slice *= 1000;
209:
210: for (i = t = 0; i < MAX_GPIO_PINS; t = 0, i++) {
211: if ((ret = gpioRead(i)) == -1)
212: return 127;
213:
214: if (ret != ((states >> i) & 0x1)) {
215: if (!i) { /* button */
216: t = 0;
217: do {
218: t++;
219: usleep(slice);
220: if (gpioRead(i) != ret)
221: break;
222: } while (!Kill);
223: } else { /* leds */
224: t = ret;
225: if (ret)
226: states |= (1 << i);
227: else
228: states &= ~(1 << i);
229: }
230:
231: RunCmd(i, t);
232: }
233: }
234:
235: usleep(slice);
236: }
237:
238: return 0;
239: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>