First test for curtain control
authorArjen Baart <arjen@andromeda.nl>
Thu, 2 Apr 2020 06:11:59 +0000 (08:11 +0200)
committerArjen Baart <arjen@andromeda.nl>
Thu, 2 Apr 2020 06:11:59 +0000 (08:11 +0200)
src/Makefile.am
src/curtain.c [new file with mode: 0644]

index 0507dc3..702824d 100644 (file)
@@ -1,7 +1,8 @@
-bin_PROGRAMS = wakeup pwm lightcontrol sunrise read_serial
+bin_PROGRAMS = wakeup pwm curtain lightcontrol sunrise read_serial
 
 wakeup_SOURCES = wakeup.cpp event.cpp
 pwm_SOURCES = pwm.c
+curtain_SOURCES = curtain.c
 lightcontrol_SOURCES = lightcontrol.cpp logging.cpp
 
 sunrise_SOURCES = sunrise.cpp
diff --git a/src/curtain.c b/src/curtain.c
new file mode 100644 (file)
index 0000000..46f2e61
--- /dev/null
@@ -0,0 +1,111 @@
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define PAGE_SIZE (4*1024)
+#define BLOCK_SIZE (4*1024)
+/*  Direct access to GPIO hardware  */
+
+// Access from ARM Running Linux
+// For Raspberry Pi 2 and Pi 3, change BCM2708_PERI_BASE to 0x3F000000 for the code to work.
+//#define BCM2708_PERI_BASE        0x20000000
+#define BCM2708_PERI_BASE        0x3F000000
+#define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
+// I/O access
+volatile unsigned *gpio;
+// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
+#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
+#define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))
+#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
+#define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0
+#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
+#define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH
+#define GPIO_PULL *(gpio+37) // Pull up/pull down
+#define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
+void setup_io();
+
+
+/*  GPIO pin assignments */
+
+#define OPEN_OUT     19
+#define OPEN_IN      16
+#define CLOSE_OUT    26
+#define CLOSE_IN     20
+
+
+int main()
+{
+   int i;
+
+   // Set up gpi pointer for direct register access
+   setup_io();
+   INP_GPIO(OPEN_OUT); // must use INP_GPIO before we can use OUT_GPIO
+   OUT_GPIO(OPEN_OUT);
+   INP_GPIO(OPEN_IN);
+
+   INP_GPIO(CLOSE_OUT); // must use INP_GPIO before we can use OUT_GPIO
+   OUT_GPIO(CLOSE_OUT);
+   INP_GPIO(CLOSE_IN);
+
+   GPIO_SET = 1 << OPEN_OUT;   //  Close the switch
+   sleep(1);
+   GPIO_CLR = 1 << OPEN_OUT;   //  Open the switch
+
+   return 0;
+}
+
+//
+// Set up a memory regions to access GPIO
+//
+void setup_io()
+{
+   void *gpio_map;
+   int  mem_fd;
+
+   /* open /dev/mem */
+   if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0)
+   {
+      printf("can't open /dev/mem \n");
+      exit(-1);
+   }
+   /* mmap GPIO */
+   gpio_map = mmap(
+      NULL,             //Any adddress in our space will do
+      BLOCK_SIZE,       //Map length
+      PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
+      MAP_SHARED,       //Shared with other processes
+      mem_fd,           //File to map
+      GPIO_BASE         //Offset to GPIO peripheral
+   );
+   close(mem_fd); //No need to keep mem_fd open after mmap
+   if (gpio_map == MAP_FAILED)
+   {
+      printf("mmap error %d, errno = %d\n", gpio_map, errno);//errno also set!
+      exit(-1);
+   }
+   // Always use volatile pointer!
+   gpio = (volatile unsigned *)gpio_map;
+} // setup_io