chiark / gitweb /
wiringpi: much implementation
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 8 Jun 2016 01:37:30 +0000 (02:37 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 8 Jun 2016 01:37:30 +0000 (02:37 +0100)
wiringpi/wiringpi.c
wiringpi/wiringpi.tct

index f3b7cb8..32b1470 100644 (file)
 #include "chiark_tcl_wiringpi.h"
 
 #include "wiringPi.h"
+#include <piFace.h>
 
 /*---------- important types and forward declarations ----------*/
 
-static int ensure_setup(void) {
-  return TCL_OK;
-}
-
-/*---------- operations ----------*/
-
 #define CHECK_SETUP                            \
   int rc;                                      \
-  rc = ensure_setup();                         \
+  rc = ensure_setup(ip);                       \
   if (rc) return rc; else
 
 #define CHECK_RANGE(val, min, max, what, VAL) do{              \
@@ -75,6 +70,63 @@ static int ensure_setup(void) {
                           "WIRINGPI RANGE " VAL " MAX " #max); \
   }while(0)
 
+static int setup_done;
+
+/*---------- operations ----------*/
+
+static int setup_failure(Tcl_Interp *ip, int r) {
+#define N 4
+  Tcl_Obj *codelist[N];
+  codelist[0]= cht_ret_string(ip,"WIRINGPI");
+  codelist[1]= cht_ret_string(ip,"ERROR");
+  codelist[2]= cht_ret_string(ip,"SETUP");
+  codelist[3]= cht_ret_int(ip,r);
+  Tcl_SetObjResult(ip, Tcl_NewListObj(N, codelist));
+#undef N
+  Tcl_SetResult(ip, (char*)"wiringpi initialisation error", TCL_STATIC);
+  return TCL_ERROR;
+}
+
+static int ensure_setup(Tcl_Interp *ip) {
+  if (!setup_done) {
+    int r = wiringPiSetup();
+    if (r) return setup_failure(ip, r);
+    setup_done = 1;
+  }
+  return TCL_OK;
+}
+
+int cht_do_wiringpitcl_setup(ClientData cd, Tcl_Interp *ip,
+                            int objc, Tcl_Obj *const *objv) {
+  int r;
+  int rc;
+
+  if (setup_done)
+    return cht_staticerr(ip,"wiringpi setup called again",
+                        "WIRINGPI FORBIDDEN-REINIT SETUP");
+
+  if (*objv) {
+    const char *modeopt;
+    rc = cht_pat_string(ip,*objv++,&modeopt);
+    if (rc) return rc;
+    if (modeopt[0] != '-' || !modeopt[1] || modeopt[2])
+      return cht_staticerr(ip,"wiringpi setup option wrong syntax", 0);
+    if (*objv)
+      return cht_staticerr(ip,"wiringpi setup too many arguments", 0);
+    switch (modeopt[1]) {
+    case 'g':  r = wiringPiSetupGpio();                             break;
+    case '1':  r = wiringPiSetupPhys();                             break;
+    case 'p':  r = piFaceSetup(2000 /* ?! copied from gpio.c* */);  break;
+    default:
+      return cht_staticerr(ip,"wiringpi setup option unknown value", 0);
+    }
+  } else {
+    r = wiringPiSetup();
+  }
+  if (r) return setup_failure(ip, r);
+  return TCL_OK;
+}
+
 int cht_do_wiringpitcl_pwmc(ClientData cd, Tcl_Interp *ip, int divider) {
   CHECK_SETUP;
   CHECK_RANGE(divider,1,4095,"divider for pwmc","DIVIDER");
@@ -82,6 +134,13 @@ int cht_do_wiringpitcl_pwmc(ClientData cd, Tcl_Interp *ip, int divider) {
   return TCL_OK;
 }
 
+int cht_do_wiringpitcl_pwmr(ClientData cd, Tcl_Interp *ip, int range) {
+  CHECK_SETUP;
+  CHECK_RANGE(range,1,INT_MAX,"pwm range","RANGE");
+  pwmSetRange(range);
+  return TCL_OK;
+}
+
 int cht_do_wiringpitcl_boardId(ClientData cd, Tcl_Interp *ip,
                               Tcl_Obj **result) {
 #define N 5
@@ -159,8 +218,7 @@ const WiringPiTclModeInfo cht_wiringpitclmodeinfo_entries[] = {
 
 int cht_do_wiringpitcl_mode(ClientData cd, Tcl_Interp *ip, int pin,
                            const WiringPiTclModeInfo *mode) {
-  int rc;
-  rc = ensure_setup();  if (rc) return rc;
+  CHECK_SETUP;
   mode->func(pin);
   return TCL_OK;
 }
index c25d0ae..d2e4bab 100644 (file)
@@ -51,7 +51,6 @@ Table wiringpitcl WiringPiTcl_SubCommand
                pin     int
                val     int
        pwmr
-               pin     int
                val     int
        pwm-bal
        pwm-ms