2 * wiringpi setup [MODE]
3 * MODE is one of -g -1 -p, as for gpio(1)
4 * optional, if not called is equivalent to saying just "setup"
5 * may not be called after any other wiringpi use in whole program
6 * there is no way to un-setup
8 * Most of the rest are very similar to gpio(1):
9 * boardRev => integer (see wiringPi.h)
10 * boardId => [list MODEL REV MEM MAKER OVERVOLTED]
13 * in out pwm pwmTone clock up down tri off
14 * alt0 alt1 alt2 alt3 alt4 alt5
26 /* ---8<--- end of documentation comment --8<-- */
29 * wiringpi.c - wiringPi binding for Tcl
30 * Copyright 2016 Ian Jackson
32 * This program is free software; you can redistribute it and/or
33 * modify it under the terms of the GNU General Public License as
34 * published by the Free Software Foundation; either version 2 of the
35 * License, or (at your option) any later version.
37 * This program is distributed in the hope that it will be useful, but
38 * WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
40 * General Public License for more details.
42 * You should have received a copy of the GNU General Public License
43 * along with this library; if not, see <http://www.gnu.org/licenses/>.
50 #include "chiark_tcl_wiringpi.h"
54 /*---------- important types and forward declarations ----------*/
58 rc = ensure_setup(ip); \
59 if (rc) return rc; else
61 #define CHECK_RANGE(val, min, max, what, VAL) do{ \
63 return cht_staticerr(ip, what " too small" \
64 " (must be at least" #min ")", \
65 "WIRINGPI RANGE " VAL " MIN " #min); \
67 return cht_staticerr(ip, what " too large" \
68 " (must be at most" #max ")", \
69 "WIRINGPI RANGE " VAL " MAX " #max); \
72 static int setup_done;
74 /*---------- operations ----------*/
76 static int setup_failure(Tcl_Interp *ip, int r) {
79 codelist[0]= cht_ret_string(ip,"WIRINGPI");
80 codelist[1]= cht_ret_string(ip,"ERROR");
81 codelist[2]= cht_ret_string(ip,"SETUP");
82 codelist[3]= cht_ret_int(ip,r);
83 Tcl_SetObjResult(ip, Tcl_NewListObj(N, codelist));
85 Tcl_SetResult(ip, (char*)"wiringpi initialisation error", TCL_STATIC);
89 static int ensure_setup(Tcl_Interp *ip) {
91 int r = wiringPiSetup();
92 if (r) return setup_failure(ip, r);
98 int cht_do_wiringpitcl_setup(ClientData cd, Tcl_Interp *ip,
99 int objc, Tcl_Obj *const *objv) {
104 return cht_staticerr(ip,"wiringpi setup called again",
105 "WIRINGPI FORBIDDEN-REINIT SETUP");
109 rc = cht_pat_string(ip,*objv++,&modeopt);
111 if (modeopt[0] != '-' || !modeopt[1] || modeopt[2])
112 return cht_staticerr(ip,"wiringpi setup option wrong syntax", 0);
114 return cht_staticerr(ip,"wiringpi setup too many arguments", 0);
115 switch (modeopt[1]) {
116 case 'g': r = wiringPiSetupGpio(); break;
117 case '1': r = wiringPiSetupPhys(); break;
119 return cht_staticerr(ip,"wiringpi setup option unknown value", 0);
124 if (r) return setup_failure(ip, r);
128 int cht_do_wiringpitcl_boardId(ClientData cd, Tcl_Interp *ip,
140 for (i=0; i<N; i++) objl[i]= cht_ret_int(ip, ints[i]);
141 *result= Tcl_NewListObj(N,objl);
146 int cht_do_wiringpitcl_boardRev(ClientData cd, Tcl_Interp *ip, int *result) {
148 *result = piBoardRev();
152 int cht_do_wiringpitcl_pwmc(ClientData cd, Tcl_Interp *ip, int divider) {
154 CHECK_RANGE(divider,1,4095,"divider for pwmc","DIVIDER");
155 pwmSetClock(divider);
159 int cht_do_wiringpitcl_pwmr(ClientData cd, Tcl_Interp *ip, int range) {
161 CHECK_RANGE(range,1,INT_MAX,"pwm range","RANGE");
166 int cht_do_wiringpitcl_pwm_bal(ClientData cd, Tcl_Interp *ip) {
168 pwmSetMode(PWM_MODE_BAL);
172 int cht_do_wiringpitcl_pwm_ms(ClientData cd, Tcl_Interp *ip) {
174 pwmSetMode(PWM_MODE_MS);
178 /*---------- families of operations ----------*/
180 #define SIMPLE_READER_OP(op, wpicall) \
181 int cht_do_wiringpitcl_##op(ClientData cd, Tcl_Interp *ip, \
182 int pin, int *result) { \
184 *result = wpicall(pin); \
188 SIMPLE_READER_OP(read, digitalRead)
189 SIMPLE_READER_OP(aread, analogRead)
191 #define SIMPLE_WRITER_OP(op, min, max, wpicall) \
192 int cht_do_wiringpitcl_##op(ClientData cd, Tcl_Interp *ip, \
193 int pin, int val) { \
195 CHECK_RANGE(val,min,max, "value for " #op, "VAL"); \
200 SIMPLE_WRITER_OP(pwm, INT_MIN,INT_MAX, pwmWrite)
201 SIMPLE_WRITER_OP(awrite, INT_MIN,INT_MAX, analogWrite)
202 SIMPLE_WRITER_OP(write, 0, 1, digitalWrite)
203 SIMPLE_WRITER_OP(pwmTone, INT_MIN,INT_MAX, pwmToneWrite)
204 SIMPLE_WRITER_OP(clock, INT_MIN,INT_MAX, gpioClockSet)
207 M(in, { pinMode (pin, INPUT); }) \
208 M(input, { pinMode (pin, INPUT); }) \
209 M(out, { pinMode (pin, OUTPUT); }) \
210 M(output, { pinMode (pin, OUTPUT); }) \
211 M(pwm, { pinMode (pin, PWM_OUTPUT); }) \
212 M(pwmTone, { pinMode (pin, PWM_TONE_OUTPUT); }) \
213 M(clock, { pinMode (pin, GPIO_CLOCK); }) \
214 M(up, { pullUpDnControl(pin, PUD_UP); }) \
215 M(down, { pullUpDnControl(pin, PUD_DOWN); }) \
216 M(tri, { pullUpDnControl(pin, PUD_OFF); }) \
217 M(off, { pullUpDnControl(pin, PUD_OFF); }) \
218 M(alt0, { pinModeAlt(pin, 0b100); }) \
219 M(alt1, { pinModeAlt(pin, 0b101); }) \
220 M(alt2, { pinModeAlt(pin, 0b110); }) \
221 M(alt3, { pinModeAlt(pin, 0b111); }) \
222 M(alt4, { pinModeAlt(pin, 0b011); }) \
223 M(alt5, { pinModeAlt(pin, 0b010); })
225 #define MODE_FUNC(name, body) static void mode_##name(int pin) { body }
228 const WiringPiTclModeInfo cht_wiringpitclmodeinfo_entries[] = {
229 #define MODEINFO_ENTRY(name, body) { #name, mode_##name },
230 MODES(MODEINFO_ENTRY)
234 int cht_do_wiringpitcl_mode(ClientData cd, Tcl_Interp *ip, int pin,
235 const WiringPiTclModeInfo *mode) {
242 /*---------- main hooks for tcl ----------*/
244 CHT_INIT(wiringpi, {}, CHTI_COMMANDS(cht_wiringpitoplevel_entries))