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

index 89d849d..d5ada8a 100644 (file)
 
 #include "chiark-tcl.h"
 
+typedef struct {
+  const char *name;
+  void (*func)(int pin);
+} WiringPiTclModeInfo;
+
 #include "wiringpi+tcmdif.h"
 
 #endif /*WIRINGPITCL_H*/
index e71cb53..f3b7cb8 100644 (file)
  *   write PIN VAL
  *   pwm PIN VAL
  *   clock PIN FREQ
- *   drive GROUP VALUE
- *   pwm-bal|pwm-ms PIN
- *   pwmr PIN RANGE
- *   pwmc PIN CLOCK
+ *   pwm-bal|pwm-ms
+ *   pwmr RANGE
+ *   pwmc DIVIDER
  *   pwmTone PIN FREQ
  */
 /* ---8<--- end of documentation comment --8<-- */
 
 #include "chiark_tcl_wiringpi.h"
 
+#include "wiringPi.h"
+
 /*---------- important types and forward declarations ----------*/
 
+static int ensure_setup(void) {
+  return TCL_OK;
+}
+
+/*---------- operations ----------*/
+
+#define CHECK_SETUP                            \
+  int rc;                                      \
+  rc = ensure_setup();                         \
+  if (rc) return rc; else
+
+#define CHECK_RANGE(val, min, max, what, VAL) do{              \
+    if (val < (min))                                           \
+      return cht_staticerr(ip, what " too small"               \
+                          " (must be at least" #min ")",       \
+                          "WIRINGPI RANGE " VAL " MIN " #min); \
+    if (val > (max))                                           \
+      return cht_staticerr(ip, what " too large"               \
+                          " (must be at most" #max ")",        \
+                          "WIRINGPI RANGE " VAL " MAX " #max); \
+  }while(0)
+
+int cht_do_wiringpitcl_pwmc(ClientData cd, Tcl_Interp *ip, int divider) {
+  CHECK_SETUP;
+  CHECK_RANGE(divider,1,4095,"divider for pwmc","DIVIDER");
+  pwmSetClock(divider);
+  return TCL_OK;
+}
+
+int cht_do_wiringpitcl_boardId(ClientData cd, Tcl_Interp *ip,
+                              Tcl_Obj **result) {
+#define N 5
+  CHECK_SETUP;
+  int ints[N];
+  Tcl_Obj *objl[N];
+  piBoardId(&ints[0],
+           &ints[1],
+           &ints[2],
+           &ints[3],
+           &ints[4]);
+  int i;
+  for (i=0; i<N; i++) objl[i]= Tcl_NewIntObj(ints[i]);
+  *result= Tcl_NewListObj(N,objl);
+  return TCL_OK;
+#undef N
+}
+
+int cht_do_wiringpitcl_boardRev(ClientData cd, Tcl_Interp *ip, int *result) {
+  CHECK_SETUP;
+  *result = piBoardRev();
+  return TCL_OK;
+}
+
+/*---------- families operations ----------*/
+
+int cht_do_wiringpitcl_aread(ClientData cd, Tcl_Interp *ip, int pin, int *result) {
+  CHECK_SETUP;
+  *result = analogRead(pin);
+  return TCL_OK;
+}
+
+#define SIMPLE_WRITER_OP(op, min, max, wpicall)                        \
+  int cht_do_wiringpitcl_##op(ClientData cd, Tcl_Interp *ip,   \
+                             int pin, int val) {               \
+    CHECK_SETUP                                                        \
+    CHECK_RANGE(val,min,max, "value for " #op, "VAL");         \
+    wpicall(pin, val);                                         \
+    return TCL_OK;                                             \
+  }
+
+SIMPLE_WRITER_OP(pwm,     INT_MIN,INT_MAX, pwmWrite)
+SIMPLE_WRITER_OP(awrite,  INT_MIN,INT_MAX, analogWrite)
+SIMPLE_WRITER_OP(write,   0,      1,       digitalWrite)
+SIMPLE_WRITER_OP(pwmTone, INT_MIN,INT_MAX, pwmToneWrite)
+SIMPLE_WRITER_OP(clock,   INT_MIN,INT_MAX, gpioClockSet)
+
+#define MODES(M)                                               \
+  M(in,       { pinMode        (pin, INPUT); })                        \
+  M(input,    { pinMode        (pin, INPUT); })                        \
+  M(out,      { pinMode        (pin, OUTPUT); })               \
+  M(output,   { pinMode        (pin, OUTPUT); })               \
+  M(pwm,      { pinMode        (pin, PWM_OUTPUT); })           \
+  M(pwmTone,  { pinMode        (pin, PWM_TONE_OUTPUT); })      \
+  M(clock,    { pinMode        (pin, GPIO_CLOCK); })           \
+  M(up,       { pullUpDnControl(pin, PUD_UP); })               \
+  M(down,     { pullUpDnControl(pin, PUD_DOWN); })             \
+  M(tri,      { pullUpDnControl(pin, PUD_OFF); })              \
+  M(off,      { pullUpDnControl(pin, PUD_OFF); })              \
+  M(alt0,     { pinModeAlt(pin, 0b100); })                     \
+  M(alt1,     { pinModeAlt(pin, 0b101); })                     \
+  M(alt2,     { pinModeAlt(pin, 0b110); })                     \
+  M(alt3,     { pinModeAlt(pin, 0b111); })                     \
+  M(alt4,     { pinModeAlt(pin, 0b011); })                     \
+  M(alt5,     { pinModeAlt(pin, 0b010); })
+
+#define MODE_FUNC(name, body) static void mode_##name(int pin) { body }
+  MODES(MODE_FUNC)
+
+const WiringPiTclModeInfo cht_wiringpitclmodeinfo_entries[] = {
+#define MODEINFO_ENTRY(name, body) { #name, mode_##name },
+  MODES(MODEINFO_ENTRY)
+  { 0 },
+};
+
+int cht_do_wiringpitcl_mode(ClientData cd, Tcl_Interp *ip, int pin,
+                           const WiringPiTclModeInfo *mode) {
+  int rc;
+  rc = ensure_setup();  if (rc) return rc;
+  mode->func(pin);
+  return TCL_OK;
+}
+
+
 /*---------- main hooks for tcl ----------*/
 
 CHT_INIT(wiringpi, {}, CHTI_COMMANDS(cht_wiringpitoplevel_entries))
index 7aadecb..c25d0ae 100644 (file)
@@ -28,7 +28,7 @@ Table wiringpitcl WiringPiTcl_SubCommand
                =>      obj
        mode
                pin     int
-               mode    enum(WiringPiTcl_Mode/, "wiringpi pin mode")
+               mode    enum(WiringPiTclModeInfo/, "wiringpi pin mode")
        read
                pin     int
                =>      int
@@ -47,36 +47,13 @@ Table wiringpitcl WiringPiTcl_SubCommand
        clock
                pin     int
                freq    int
-       drive
-               group   int
-               value   int
-       pwm-bal
-               pin     int
-       pwm-ms
-               pin     int
        pwmTone
                pin     int
                val     int
        pwmr
                pin     int
                val     int
+       pwm-bal
+       pwm-ms
        pwmc
-               pin     int
-               clk     int
-
-Table wiringpitcl_mode WiringPiTcl_Mode
-       in
-       out
-       pwm
-       pwmTone
-       clock
-       up
-       down
-       tri
-       off
-       alt0
-       alt1
-       alt2
-       alt3
-       alt4
-       alt5
+               divider int