예제 #1
0
static gboolean
chassis_reboot(gpointer connection)
{
    int rc = 0;
    uint8_t gpio = 0;
    GDBusProxy *proxy;
    GError *error;
    GVariant *parm = NULL;
    GVariant *result = NULL;

    // The gpio line may flicker during power on/off, so check that the value
    // is still 0 (checkstopped) and that host is booted in order to reboot
    rc = gpio_open(&checkstop);
    if (rc != GPIO_OK) {
        return FALSE;
    }
    rc = gpio_read(&checkstop, &gpio);
    if (rc != GPIO_OK) {
        gpio_close(&checkstop);
        return FALSE;
    }
    gpio_close(&checkstop);
    if ((!gpio) && (is_host_booted(connection)))
    {
        printf("Host Checkstop, rebooting host\n");
        error = NULL;
        proxy = g_dbus_proxy_new_sync((GDBusConnection*)connection,
            G_DBUS_PROXY_FLAGS_NONE,
            NULL, /* GDBusInterfaceInfo* */
            "org.openbmc.control.Chassis", /* name */
            "/org/openbmc/control/chassis0", /* object path */
            "org.openbmc.control.Chassis", /* interface name */
            NULL, /* GCancellable */
            &error);
        g_assert_no_error(error);

        error = NULL;
        result = g_dbus_proxy_call_sync(proxy,
            "reboot",
            parm,
            G_DBUS_CALL_FLAGS_NONE,
            -1,
            NULL,
            &error);
        g_assert_no_error(error);
    }

    return FALSE;
}
예제 #2
0
// python function cleanup()
static PyObject *py_cleanup(PyObject *self, PyObject *args)
{
    gpio_close();
    
   Py_INCREF(Py_None);
   return Py_None;
}
예제 #3
0
pwm_driver2_t* pwm_driver2_open(pwm_driver2_descriptor_ptr driver) {
  if (!pwm_driver2_prepare_device(driver)) {
    printf("Cannot prepare driver %d\n", driver->id);
    return NULL;
  }
  pwm_driver2_t* pwm_driver2 = malloc(sizeof(pwm_driver2_t));
  pwm_driver2->pwm = pwm_open(driver->pwm, 50000);
  if (!pwm_driver2->pwm) {
    free(pwm_driver2);
    return NULL;
  }
  pwm_driver2->direction = gpio_open(driver->direction, GPIO_OUT);
  if (!pwm_driver2->direction) {
    pwm_close(pwm_driver2->pwm);
    free(pwm_driver2);
    return NULL;
  }
  pwm_driver2->enable = driver->enable;
  if (!gpio_write_direction_file(pwm_driver2->enable, GPIO_OUT)) {
    pwm_close(pwm_driver2->pwm);
    gpio_close(pwm_driver2->direction);
    free(pwm_driver2);
    return NULL;
  }
  pwm_driver2->pwm->zero = 0;
  pwm_set_duty(pwm_driver2->pwm, pwm_driver2->pwm->zero);
  gpio_write_value_file(pwm_driver2->enable, 0);
  return pwm_driver2;
}
예제 #4
0
void pwm_driver2_close(pwm_driver2_t* pwm_driver2) {
  if (pwm_driver2 == NULL)
    return;
  gpio_write_value_file(pwm_driver2->enable, 0);
  gpio_close(pwm_driver2->direction);
  pwm_close(pwm_driver2->pwm);
  free(pwm_driver2);
}
예제 #5
0
int main(int argc, char *argv[])
{
    CCoreThread *core;

    appStartMs = Utils::getCurrentMs();
    
    initializeFlags();                                          // initialize flags 
    Debug::setDefaultLogFile();
    loadDefaultArgumentsFromFile();                             // first parse default arguments from file
    loadLastHwConfig();                                         // load last found HW IF, HW version, SCSI machine
    
    printf("CosmosEx preinit app starting...\n");
    //------------------------------------
    if(signal(SIGINT, sigint_handler) == SIG_ERR) {		    // register SIGINT handler
        printf("Cannot register SIGINT handler!\n");
    }

    if(signal(SIGHUP, sigint_handler) == SIG_ERR) {		    // register SIGHUP handler
        printf("Cannot register SIGHUP handler!\n");
    }

    //------------------------------------
    // normal app run follows
    Debug::printfLogLevelString();

    char appVersion[16];
    Version::getAppVersion(appVersion);
    
    Debug::out(LOG_INFO, "\n\n---------------------------------------------------");
    Debug::out(LOG_INFO, "CosmosEx preinit starting, version: %s", appVersion);

//	system("sudo echo none > /sys/class/leds/led0/trigger");	    // disable usage of GPIO 23 (pin 16) by LED

	if(!gpio_open()) {									            // try to open GPIO and SPI on RPi
		return 0;
	}

    //-------------
    // Copy the configdrive to /tmp so we can change the content as needed.
    // This must be done before new CCoreThread because it reads the data from /tmp/configdrive 
    system("rm -rf /tmp/configdrive");                      // remove any old content
    system("mkdir /tmp/configdrive");                       // create dir
    system("cp -r /ce/app/configdrive/* /tmp/configdrive"); // copy new content
    //-------------
    core = new CCoreThread();
    
	core->run();										// run the main thread

	delete core;
	gpio_close();										// close gpio and spi

    Debug::out(LOG_INFO, "CosmosEx preinit terminated.");
    printf("Preinit terminated\n");
    return 0;
}
예제 #6
0
int get_presence(GDBusConnection* connection, GPIO* gpio, uint8_t* present)
{
	int rc = GPIO_OK;
	do {
		rc = gpio_init(connection,gpio);
		if (rc != GPIO_OK) { break; }
		uint8_t gpio_val;
		rc = gpio_open(gpio);
		if (rc != GPIO_OK) { break; }
		rc = gpio_read(gpio,&gpio_val);
		if (rc != GPIO_OK) { gpio_close(gpio); break; }
		gpio_close(gpio);
		*present = gpio_val;	
	} while(0);
	if (rc != GPIO_OK)
	{
		printf("ERROR pcie_slot_present: GPIO error %s (rc=%d)\n",gpio->name,rc);
	}
	return rc; 
}
예제 #7
0
파일: toolbar.c 프로젝트: pa3gsb/RadioBerry
static void stop() {
  if(protocol==ORIGINAL_PROTOCOL) {
    old_protocol_stop();
  } 
  if(protocol==NEW_PROTOCOL){
    new_protocol_stop();
  }
   if(protocol==RADIOBERRY_PROTOCOL){
   radioberry_protocol_stop();
  }
  gpio_close();
}
예제 #8
0
static int lua_gpio_close(lua_State *L) {
    gpio_t *gpio;
    int ret;

    gpio = luaL_checkudata(L, 1, "periphery.GPIO");

    if ((ret = gpio_close(gpio)) < 0)
        return lua_gpio_error(L, ret, gpio_errno(gpio), "Error: %s", gpio_errmsg(gpio));

    gpio->fd = -1;

    return 0;
}
예제 #9
0
void cycle11 (void) {
    if (do_cycle11 == 1) {
        // Set Halt
        set_halt_until_mbus_tx();

        gpio_init(0xFFFF); // All Output
        gpio_write_data(0xF0F0); // 1111 0000 1111 0000
        gpio_kill_bit(15);       // 0111 0000 1111 0000
        gpio_set_bit(1);         // 0111 0000 1111 0010
        gpio_set_2bits(11, 8);   // 0111 1001 1111 0010
        gpio_kill_bit(12);       // 0110 1001 1111 0010

        if (gpio_get_data() == 0xF2) {pass (0xC, gpio_get_data());}
        else {fail (0xC, gpio_get_data());}

        gpio_close();
    }
}
예제 #10
0
static gboolean
on_set_power_state(ControlPower *pwr,
		GDBusMethodInvocation *invocation,
		guint state,
		gpointer user_data)
{
	Control* control = object_get_control((Object*)user_data);
	if(state > 1)
	{
		g_dbus_method_invocation_return_dbus_error(invocation,
				"org.openbmc.ControlPower.Error.Failed",
				"Invalid power state");
		return TRUE;
	}
	// return from method call
	control_power_complete_set_power_state(pwr,invocation);
	if(state == control_power_get_state(pwr))
	{
		g_print("Power already at requested state: %d\n",state);
	}
	else
	{
		int error = 0;
		do {
			if(state == 1) {
				control_emit_goto_system_state(control,"HOST_POWERING_ON");
			} else {
				control_emit_goto_system_state(control,"HOST_POWERING_OFF");
			}
			error = gpio_open(&power_pin);
			if(error != GPIO_OK) { break;	}
			error = gpio_write(&power_pin,!state);
			if(error != GPIO_OK) { break;	}
			gpio_close(&power_pin);
			control_power_set_state(pwr,state);
		} while(0);
		if(error != GPIO_OK)
		{
			printf("ERROR PowerControl: GPIO set power state (rc=%d)\n",error);
		}
	}
	return TRUE;
}
예제 #11
0
파일: exit_menu.c 프로젝트: g0orx/pihpsdr
static gboolean exit_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
#ifdef GPIO
  gpio_close();
#endif
  switch(protocol) {
    case ORIGINAL_PROTOCOL:
      old_protocol_stop();
      break;
    case NEW_PROTOCOL:
      new_protocol_stop();
      break;
#ifdef LIMESDR
    case LIMESDR_PROTOCOL:
      lime_protocol_stop();
      break;
#endif
  }
  radioSaveState();
  _exit(0);
}
예제 #12
0
파일: main.c 프로젝트: g0orx/pihpsdr
gboolean main_delete (GtkWidget *widget) {
#ifdef GPIO
  gpio_close();
#endif
  switch(protocol) {
    case ORIGINAL_PROTOCOL:
      old_protocol_stop();
      break;
    case NEW_PROTOCOL:
      new_protocol_stop();
      break;
#ifdef LIMESDR
    case LIMESDR_PROTOCOL:
      lime_protocol_stop();
      break;
#endif
  }
  radioSaveState();
  _exit(0);
}
예제 #13
0
// TODO:  Change to interrupt driven instead of polling
static gboolean
poll_pgood(gpointer user_data)
{
	ControlPower *control_power = object_get_control_power((Object*)user_data);
	Control* control = object_get_control((Object*)user_data);

	//send the heartbeat
	guint poll_int = control_get_poll_interval(control);
	if(poll_int == 0)
	{
		printf("ERROR PowerControl: Poll interval cannot be 0\n");
		return FALSE;
	}
	//handle timeout
	time_t current_time = time(NULL);
	if(difftime(current_time,pgood_timeout_start) > control_power_get_pgood_timeout(control_power)
			&& pgood_timeout_start != 0)
	{
		printf("ERROR PowerControl: Pgood poll timeout\n");
		// set timeout to 0 so timeout doesn't happen again
		control_power_set_pgood_timeout(control_power,0);
		pgood_timeout_start = 0;
		return TRUE;
	}
	uint8_t gpio;

	int rc = gpio_open(&pgood);
	rc = gpio_read(&pgood,&gpio);
	gpio_close(&pgood);
	if(rc == GPIO_OK)
	{
		//if changed, set property and emit signal
		if(gpio != control_power_get_pgood(control_power))
		{
			control_power_set_pgood(control_power,gpio);
			if(gpio==0)
			{
				control_power_emit_power_lost(control_power);
				control_emit_goto_system_state(control,"HOST_POWERED_OFF");
				rc = gpio_open(&pcie_reset);
				rc = gpio_write(&pcie_reset,0);
				gpio_close(&pcie_reset);

				rc = gpio_open(&usb_reset);
				rc = gpio_write(&usb_reset,0);
				gpio_close(&usb_reset);

			}
			else
			{
				control_power_emit_power_good(control_power);
				control_emit_goto_system_state(control,"HOST_POWERED_ON");
				rc = gpio_open(&pcie_reset);
				rc = gpio_write(&pcie_reset,1);
				gpio_close(&pcie_reset);

				rc = gpio_open(&usb_reset);
				rc = gpio_write(&usb_reset,1);
				gpio_close(&usb_reset);
			}
		}
	} else {
		printf("ERROR PowerControl: GPIO read error (gpio=%s,rc=%d)\n",pgood.name,rc);
		//return false so poll won't get called anymore
		return FALSE;
	}
	//pgood is not at desired state yet
	if(gpio != control_power_get_state(control_power) &&
			control_power_get_pgood_timeout(control_power) > 0)
	{
		if(pgood_timeout_start == 0 ) {
			pgood_timeout_start = current_time;
		}
	}
	else
	{
		pgood_timeout_start = 0;
	}
	return TRUE;
}
예제 #14
0
void oled_close(void)
{
	gpio_close();
}
예제 #15
0
파일: gpioctl.c 프로젝트: mr-justin/freebsd
int
main(int argc, char **argv)
{
	int i;
	gpio_config_t pin;
	gpio_handle_t handle;
	char *ctlfile = NULL;
	int pinn, pinv, ch;
	int flags, flag, ok;
	int config, toggle, verbose, list;

	config = toggle = verbose = list = pinn = 0;

	while ((ch = getopt(argc, argv, "c:f:lt:v")) != -1) {
		switch (ch) {
		case 'c':
			config = 1;
			pinn = str2int(optarg, &ok);
			if (!ok)
				fail("Invalid pin number: %s\n", optarg);
			break;
		case 'f':
			ctlfile = optarg;
			break;
		case 'l':
			list = 1;
			break;
		case 't':
			toggle = 1;
			pinn = str2int(optarg, &ok);
			if (!ok)
				fail("Invalid pin number: %s\n", optarg);
			break;
		case 'v':
			verbose = 1;
			break;
		default:
			usage();
			break;
		}
	}
	argv += optind;
	argc -= optind;
	if (ctlfile == NULL)
		handle = gpio_open(0);
	else
		handle = gpio_open_device(ctlfile);
	if (handle == GPIO_INVALID_HANDLE) {
		perror("gpio_open");
		exit(1);
	}

	if (list) {
		dump_pins(handle, verbose);
		gpio_close(handle);
		exit(0);
	}

	if (toggle) {
		/*
		 * -t pin assumes no additional arguments
		 */
		if (argc > 0) {
			usage();
			exit(1);
		}
		if (gpio_pin_toggle(handle, pinn) < 0) {
			perror("gpio_pin_toggle");
			exit(1);
		}
		gpio_close(handle);
		exit(0);
	}

	if (config) {
		flags = 0;
		for (i = 0; i < argc; i++) {
			flag = 	str2cap(argv[i]);
			if (flag < 0)
				fail("Invalid flag: %s\n", argv[i]);
			flags |= flag;
		}
		pin.g_pin = pinn;
		pin.g_flags = flags;
		if (gpio_pin_set_flags(handle, &pin) < 0) {
			perror("gpio_pin_set_flags");
			exit(1);
		}
		exit(0);
	}

	/*
	 * Last two cases - set value or print value
	 */
	if ((argc == 0) || (argc > 2)) {
		usage();
		exit(1);
	}

	pinn = str2int(argv[0], &ok);
	if (!ok)
		fail("Invalid pin number: %s\n", argv[0]);

	/*
	 * Read pin value
	 */
	if (argc == 1) {
		pinv = gpio_pin_get(handle, pinn);
		if (pinv < 0) {
			perror("gpio_pin_get");
			exit(1);
		}
		printf("%d\n", pinv);
		exit(0);
	}

	/* Is it valid number (0 or 1) ? */
	pinv = str2int(argv[1], &ok);
	if (!ok || ((pinv != 0) && (pinv != 1)))
		fail("Invalid pin value: %s\n", argv[1]);

	/*
	 * Set pin value
	 */
	if (gpio_pin_set(handle, pinn, pinv) < 0) {
		perror("gpio_pin_set");
		exit(1);
	}

	gpio_close(handle);
	exit(0);
}
예제 #16
0
static void
on_bus_acquired(GDBusConnection *connection,
		const gchar *name,
		gpointer user_data)
{
	ObjectSkeleton *object;
	cmdline *cmd = user_data;
	if(cmd->argc < 3)
	{
		g_print("Usage: power_control.exe [poll interval] [timeout]\n");
		return;
	}
	manager = g_dbus_object_manager_server_new(dbus_object_path);
	gchar *s;
	s = g_strdup_printf("%s/%s",dbus_object_path,instance_name);
	object = object_skeleton_new(s);
	g_free(s);

	ControlPower* control_power = control_power_skeleton_new();
	object_skeleton_set_control_power(object, control_power);
	g_object_unref(control_power);

	Control* control = control_skeleton_new();
	object_skeleton_set_control(object, control);
	g_object_unref(control);

	//define method callbacks here
	g_signal_connect(control_power,
			"handle-set-power-state",
			G_CALLBACK(on_set_power_state),
			object); /* user_data */

	g_signal_connect(control_power,
			"handle-get-power-state",
			G_CALLBACK(on_get_power_state),
			NULL); /* user_data */

	g_signal_connect(control,
			"handle-init",
			G_CALLBACK(on_init),
			object); /* user_data */


	/* Export the object (@manager takes its own reference to @object) */
	g_dbus_object_manager_server_set_connection(manager, connection);
	g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object));
	g_object_unref(object);

	// get gpio device paths
	int rc = GPIO_OK;
	do {
		rc = gpio_init(connection,&power_pin);
		if(rc != GPIO_OK) { break; }
		rc = gpio_init(connection,&pgood);
		if(rc != GPIO_OK) { break; }
		rc = gpio_init(connection,&pcie_reset);
		if(rc != GPIO_OK) { break; }
		rc = gpio_init(connection,&usb_reset);
		if(rc != GPIO_OK) { break; }

		uint8_t gpio;
		rc = gpio_open(&pgood);
		if(rc != GPIO_OK) { break; }
		rc = gpio_read(&pgood,&gpio);
		if(rc != GPIO_OK) { break; }
		gpio_close(&pgood);
		control_power_set_pgood(control_power,gpio);
		control_power_set_state(control_power,gpio);
		printf("Pgood state: %d\n",gpio);

	} while(0);
	if(rc != GPIO_OK)
	{
		printf("ERROR PowerControl: GPIO setup (rc=%d)\n",rc);
	}
	//start poll
	pgood_timeout_start = 0;
	int poll_interval = atoi(cmd->argv[1]);
	int pgood_timeout = atoi(cmd->argv[2]);
	if(poll_interval < 1000 || pgood_timeout <5) {
		printf("ERROR PowerControl: poll_interval < 1000 or pgood_timeout < 5\n");
	} else {
		control_set_poll_interval(control,poll_interval);
		control_power_set_pgood_timeout(control_power,pgood_timeout);
		g_timeout_add(poll_interval, poll_pgood, object);
	}
}
예제 #17
0
파일: i2c.c 프로젝트: Jufino/Software_i2c
void i2c_close(void){//ok
	gpio_close(SDA);
	gpio_close(SCL);
}
예제 #18
0
파일: soccer.c 프로젝트: Jufino/SoccerBot
//-------------------------------------------------------
void CloseSoccer(void){
	SerialClose(port);
	gpio_close(17);
	gpio_close(18);
}
예제 #19
0
파일: test.c 프로젝트: rajbot/gphoto
int main(int argc, char** argv) {
	gpio_device *dev;
	int num = -1, target_num = -1, delete_flag = 0, i = 0 ;
	char *file_prefix=NULL, *port=NULL, *filename, *srcnamebuffer, *dstnamebuffer;

#if HAVE_GETOPT || HAVE_GETOPT_LONG
	int value, opt = 0, error_flag = 0;
	extern int opterr, optind;
	extern char* optarg;

#if HAVE_GETOPT_LONG
	static struct option long_options[] = {
		{"all", no_argument, 0, 'a'},
		{"delete", no_argument, 0, 'd'},
		{"file-prefix", required_argument, 0, 'f'},
		{"number", required_argument, 0, 'n'},
		{"port",required_argument, 0, 'p'},
		{0, 0, 0, 0}
	};

	opterr = 0;
	while ((opt = getopt_long(argc, argv, "adf:n:p:", long_options, NULL)) != EOF)
#elif HAVE_GETOPT
	opterr = 0;
	while ((opt = getopt(argc, argv, "adf:n:p:")) != EOF)
#endif /* HAVE_GETOPT_LONG */
	{
		switch (opt) {
			case 'a':
				if ( target_num == -1 ) {
					target_num = 0;
				} else {
					usage_msg(argv[0]);
					fprintf(stderr, "Cannot select both all images and specific images\n");
					fflush(stderr);
					return 1;
				}
				break;
			case 'd':
				delete_flag = 1;
				break;
			case 'f':
				file_prefix = optarg;
				break;
			case 'n':
				if ( target_num == -1 ) {
					target_num = atoi(optarg);
				} else {
					usage_msg(argv[0]);
					fprintf(stderr, "Cannot select both all images and specific images\n");
					fflush(stderr);
					return 1;
				}
				break;
			case 'p':
				port = optarg;
				break;
			case '?':
			default:
				error_flag++;
				break;
		}
	}

#endif /* HAVE_GETOPT || HAVE_GETOPT_LONG */

#if DIMAGE_V_DEBUG
	debug=fopen("debug.log","w");
#endif


	if ( port ==  NULL ) {
		usage_msg(argv[0]);
		fprintf(stderr, "Must specify a value for port\n");
		fflush(stderr);
		return 1;
	}

	if ( file_prefix == NULL ) {
		fprintf(stderr, "Using file as default file prefix\n");
		fflush(stderr);
		if ( ( file_prefix = malloc(5) ) == NULL ) {
			perror("Unable to allocate file_prefix");
			return 1;
		}
		snprintf(file_prefix, 5, "file");
	}	

	if ( strlen(port) >= 20 ) {
		fprintf(stderr, "Bad value for port, using /dev/dimagev\n");
		fflush(stderr);
		snprintf(serial_port, 20, "/dev/dimagev");
	} else {
		snprintf(serial_port, 20, port);
	}
	
	dev = dimage_v_open(serial_port);
	if ( dev == NULL ) {
		fprintf(stderr, "Got a null pointer back from dimage_v_open\n");
		return 1;
	}	
	
	num = dimage_v_number_of_pictures();

	if ( num > 0 ) {
		printf("Number of pictures is %d\n", num);
		sleep(3);
	}	

	if ( target_num == 0 ) {
		for ( i = 1 ; i <= num ; i++ ) {

			printf("Picture will be named %s%04d.jpg\n", file_prefix, i);

			filename = dimage_v_write_picture_to_file(i);

			printf("filename %d is %s\n", i, filename);

			if ( dstnamebuffer == NULL ) {
				perror("Error mallocing memory for name buffers");
				gpio_close(dev);
			}	

			/* There must be a better way to see if the camera is ready... */
			sleep(3);
		}
	} else {
		/* Just get the specific image. */
		printf("Picture will be named %s%04d.jpg\n", file_prefix, target_num);
		filename = dimage_v_write_picture_to_file(target_num);
		printf("filename %d is %s\n", target_num, filename);
	}

	gpio_close(dev);
	gpio_free(dev);
	return 0;
}
예제 #20
0
int main(int argc, char * const argv[])
{
  bitbang_init_st init;
  bitbang_handle_st *hdl = NULL;
  int cs = -1, clk = -1, in = -1, out = -1;
  gpio_st cs_gpio;
  int opt;
  int is_write = 0;
  int is_read = 0;
  int read_bits = 0;
  int write_bits = 0;
  int read_bytes = 0;
  int write_bytes = 0;
  int i;
  uint8_t *read_buf = NULL;;
  uint8_t *write_buf = NULL;;
  bitbang_clk_edge_en dout_edge = BITBANG_CLK_EDGE_FALLING;
  bitbang_clk_edge_en din_edge = BITBANG_CLK_EDGE_RISING;
  bitbang_pin_value_en clk_start = BITBANG_PIN_HIGH;
  bitbang_pin_value_en cs_value = BITBANG_PIN_HIGH;
  spi_context_st ctx;
  bitbang_io_st io;
  int rc = 0;
  int binary = 0;

  memset(&ctx, sizeof(ctx), 0);
  gpio_init_default(&ctx.sc_clk);
  gpio_init_default(&ctx.sc_mosi);
  gpio_init_default(&ctx.sc_miso);
  gpio_init_default(&cs_gpio);

  while ((opt = getopt(argc, argv, "bs:S:c:C:o:O:i:I:w:r:")) != -1) {
    switch (opt) {
    case 'b':
      binary = 1;
      break;
    case 's':
      cs = atoi(optarg);
      break;
    case 'S':
      if (!strcmp(optarg, "high")) {
        cs_value = BITBANG_PIN_HIGH;
      } else if (!strcmp(optarg, "low")) {
        cs_value = BITBANG_PIN_LOW;
      } else {
        usage();
        exit(-1);
      }
      break;
    case 'c':
      clk = atoi(optarg);
      break;
    case 'C':
      if (!strcasecmp(optarg, "high")) {
        clk_start = BITBANG_PIN_HIGH;
      } else if (!strcasecmp(optarg, "low")) {
        clk_start = BITBANG_PIN_LOW;
      } else {
        usage();
        exit(-1);
      }
      break;
    case 'o':
      out = atoi(optarg);
      break;
    case 'O':
      if (!strcasecmp(optarg, "rising")) {
        dout_edge = BITBANG_CLK_EDGE_RISING;
      } else if (!strcasecmp(optarg, "falling")) {
        dout_edge = BITBANG_CLK_EDGE_FALLING;
      } else {
        usage();
        exit(-1);
      }
      break;
    case 'i':
      in = atoi(optarg);
      break;
    case 'I':
      if (!strcasecmp(optarg, "rising")) {
        din_edge = BITBANG_CLK_EDGE_RISING;
      } else if (!strcasecmp(optarg, "falling")) {
        din_edge = BITBANG_CLK_EDGE_FALLING;
      } else {
        usage();
        exit(-1);
      }
      break;
    case 'w':
      is_write = 1;
      write_bits = atoi(optarg);
      if (write_bits <= 0) {
        usage();
        exit(-1);
      }
      break;
    case 'r':
      is_read = 1;
      read_bits = atoi(optarg);
      if (read_bits <= 0) {
        usage();
        exit(-1);
      }
      break;
    default:
      usage();
      exit(-1);
    }
  }

  if (clk < 0 || in < 0 || out < 0) {
    usage();
    exit(-1);
  }

  if ((!is_read && !is_write)) {
    usage();
    exit(-1);
  }

  write_bytes = ((write_bits + 7) / 8);
  if (write_bytes) {
    write_buf = calloc(write_bytes, sizeof(uint8_t));
    if (!write_buf) {
      goto out;
    }
    if (binary) {
      size_t written_bytes;
      written_bytes = fread(write_buf, sizeof(*write_buf), write_bytes, stdin);
      if( written_bytes != write_bytes ) {
        goto out;
      }
    } else {
      for (i = 0; i < write_bytes && i + optind < argc; i++) {
        write_buf[i] = strtoul(argv[i + optind], NULL, 0);
      }
    }
  }

  read_bytes = ((read_bits + 7) / 8);
  if (read_bytes) {
    read_buf = calloc(read_bytes, sizeof(uint8_t));
    if (!read_buf) {
      goto out;
    }
  }

  if (gpio_open(&ctx.sc_clk, clk) || gpio_open(&ctx.sc_miso, in)
      || gpio_open(&ctx.sc_mosi, out)) {
    goto out;
  }

  /* change GPIO directions, only MISO is input, all others are output */
  if (gpio_change_direction(&ctx.sc_clk, GPIO_DIRECTION_OUT)
      || gpio_change_direction(&ctx.sc_miso, GPIO_DIRECTION_IN)
      || gpio_change_direction(&ctx.sc_mosi, GPIO_DIRECTION_OUT)) {
    goto out;
  }

  if (cs != -1) {
    if (gpio_open(&cs_gpio, cs)) {
        goto out;
    }
    if (gpio_change_direction(&cs_gpio, GPIO_DIRECTION_OUT)) {
      goto out;
    }
  }

  bitbang_init_default(&init);
  init.bbi_clk_start = clk_start;
  init.bbi_data_out = dout_edge;
  init.bbi_data_in = din_edge;
  init.bbi_freq = 1000 * 1000;   /* 1M Hz */
  init.bbi_pin_f = spi_pin_f;
  init.bbi_context = &ctx;

  hdl = bitbang_open(&init);
  if (!hdl) {
    goto out;
  }

  if (cs != -1) {
    /* have chip select */
    gpio_write(&cs_gpio, ((cs_value == BITBANG_PIN_HIGH)
                          ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW));
  }

  memset(&io, sizeof(io), 0);
  io.bbio_in_bits = read_bits;
  io.bbio_din = read_buf;
  io.bbio_out_bits = write_bits;
  io.bbio_dout = write_buf;

  rc = bitbang_io(hdl, &io);
  if (rc != 0) {
    goto out;
  }

  if (binary) {
    fwrite(read_buf, sizeof(*read_buf), read_bytes, stdout);
  } else {
    if (write_bits) {
      printf("Wrote %u bits:", write_bits);
      for (i = 0; i < write_bytes; i++) {
        printf(" %02x", write_buf[i]);
      }
      printf("\n");
    }

    if (read_bits) {
      printf("Read %u bits:", read_bits);
      for (i = 0; i < read_bytes; i++) {
        printf(" %02x", read_buf[i]);
      }
      printf("\n");
    }
  }

 out:
  if (hdl) {
    bitbang_close(hdl);
  }
  gpio_close(&ctx.sc_clk);
  gpio_close(&ctx.sc_miso);
  gpio_close(&ctx.sc_mosi);
  if (cs != -1) {
    /* reset have chip select */
    gpio_write(&cs_gpio, ((cs_value == BITBANG_PIN_HIGH)
                          ? GPIO_VALUE_LOW : GPIO_VALUE_HIGH));
    gpio_close(&cs_gpio);
  }

  if (read_buf) {
    free(read_buf);
  }
  if (write_buf) {
    free(write_buf);
  }
  return rc;
}
예제 #21
0
static gboolean
on_boot         (ControlHost        *host,
                GDBusMethodInvocation  *invocation,
                gpointer                user_data)
{
	// TODO: Add error checking
	g_print("Do Boot\n");
	int rc = GPIO_OK;

	Control* control = object_get_control((Object*)user_data);
	control_host_complete_boot(host,invocation);
	do {	
		rc |= gpio_open(&fsi_clk);
		rc |= gpio_open(&fsi_data);
		rc |= gpio_open(&fsi_enable);
		rc |= gpio_open(&cronus_sel);
		if (rc!=GPIO_OK) { break; }
		
		rc = gpio_write(&cronus_sel,1);
		//putcfam pu 281c 30000000 -p0
		char a[] = "000011111111110101111000111001100111111111111111111111111111101111111111";
		//putcfam pu 281c B0000000 -p0
		char b[] = "000011111111110101111000111000100111111111111111111111111111101101111111";

		gpio_write(&fsi_enable,1);
		gpio_write(&fsi_clk,1);
		gpio_write(&fsi_data,1);
		gpio_clock_cycle(&fsi_clk,5000);
		gpio_write(&fsi_data,0);
		gpio_clock_cycle(&fsi_clk,256);
		gpio_write(&fsi_data,1);
		gpio_clock_cycle(&fsi_clk,50);
		uint16_t i=0;
		for(i=0;i<strlen(a);i++) {
			gpio_writec(&fsi_data,a[i]);
			gpio_clock_cycle(&fsi_clk,1);
		}
		gpio_write(&fsi_data,1); /* Data standby state */
		gpio_clock_cycle(&fsi_clk,5000);

		for(i=0;i<strlen(b);i++) {
			gpio_writec(&fsi_data,b[i]);
			gpio_clock_cycle(&fsi_clk,1);
		}
		gpio_write(&fsi_data,1); /* Data standby state */
		gpio_clock_cycle(&fsi_clk,2);

	        gpio_write(&fsi_clk,0); /* hold clk low for clock mux */
	        gpio_write(&fsi_enable,0);
	        gpio_clock_cycle(&fsi_clk,16);
	        gpio_write(&fsi_clk,0); /* Data standby state */
	
	} while(0);
	if (rc != GPIO_OK)
	{
		printf("ERROR HostControl: GPIO sequence failed (rc=%d)\n",rc);
	}	
	gpio_close(&fsi_clk);
	gpio_close(&fsi_data);
	gpio_close(&fsi_enable);
	gpio_close(&cronus_sel);

	control_emit_goto_system_state(control,"HOST_BOOTING");
	
	control_host_emit_booted(host);
	return TRUE;
}
예제 #22
0
int
main(int argc, char **argv)
{
	int i;
	gpio_config_t pin;
	gpio_handle_t handle;
	char *ctlfile = NULL;
	int pinn, pinv, pin_type, ch;
	int flags, flag, ok;
	int config, list, name, toggle, verbose;

	config = toggle = verbose = list = name = pin_type = 0;

	while ((ch = getopt(argc, argv, "cf:lntvNp")) != -1) {
		switch (ch) {
		case 'c':
			config = 1;
			break;
		case 'f':
			ctlfile = optarg;
			break;
		case 'l':
			list = 1;
			break;
		case 'n':
			name = 1;
			break;
		case 'N':
			pin_type = PIN_TYPE_NAME;
			break;
		case'p':
			pin_type = PIN_TYPE_NUMBER;
			break;
		case 't':
			toggle = 1;
			break;
		case 'v':
			verbose = 1;
			break;
		default:
			usage();
			break;
		}
	}
	argv += optind;
	argc -= optind;
	if (ctlfile == NULL)
		handle = gpio_open(0);
	else
		handle = gpio_open_device(ctlfile);
	if (handle == GPIO_INVALID_HANDLE) {
		perror("gpio_open");
		exit(1);
	}

	if (list) {
		dump_pins(handle, verbose);
		gpio_close(handle);
		exit(0);
	}

	if (argc == 0)
		usage();

	/* Find the pin number by the name */
	switch (pin_type) {
	default:
		/* First test if it is a pin number */
		pinn = str2int(argv[0], &ok);
		if (ok) {
			/* Test if we have any pin named by this number and tell the user */
			if (get_pinnum_by_name(handle, argv[0]) != -1)
				fail("%s is also a pin name, use -p or -N\n", argv[0]);
		} else {
			/* Test if it is a name */
			if ((pinn = get_pinnum_by_name(handle, argv[0])) == -1)
				fail("Can't find pin named \"%s\"\n", argv[0]);
		}
		break;
	case PIN_TYPE_NUMBER:
		pinn = str2int(argv[0], &ok);
		if (!ok)
			fail("Invalid pin number: %s\n", argv[0]);
		break;
	case PIN_TYPE_NAME:
		if ((pinn = get_pinnum_by_name(handle, argv[0])) == -1)
			fail("Can't find pin named \"%s\"\n", argv[0]);
		break;
	}

	/* Set the pin name. */
	if (name) {
		if (argc != 2)
			usage();
		if (gpio_pin_set_name(handle, pinn, argv[1]) < 0) {
			perror("gpio_pin_set_name");
			exit(1);
		}
		exit(0);
	}

	if (toggle) {
		/*
                * -t pin assumes no additional arguments
                */
		if (argc > 1)
			usage();
		if (gpio_pin_toggle(handle, pinn) < 0) {
			perror("gpio_pin_toggle");
			exit(1);
		}
		gpio_close(handle);
		exit(0);
	}

	if (config) {
		flags = 0;
		for (i = 1; i < argc; i++) {
			flag = 	str2cap(argv[i]);
			if (flag < 0)
				fail("Invalid flag: %s\n", argv[i]);
			flags |= flag;
		}
		pin.g_pin = pinn;
		pin.g_flags = flags;
		if (gpio_pin_set_flags(handle, &pin) < 0) {
			perror("gpio_pin_set_flags");
			exit(1);
		}
		exit(0);
	}

	/*
	 * Last two cases - set value or print value
	 */
	if ((argc == 0) || (argc > 2))
		usage();

	/*
	 * Read pin value
	 */
	if (argc == 1) {
		pinv = gpio_pin_get(handle, pinn);
		if (pinv < 0) {
			perror("gpio_pin_get");
			exit(1);
		}
		printf("%d\n", pinv);
		exit(0);
	}

	/* Is it valid number (0 or 1) ? */
	pinv = str2int(argv[1], &ok);
	if (ok == 0 || ((pinv != 0) && (pinv != 1)))
		fail("Invalid pin value: %s\n", argv[1]);

	/*
	 * Set pin value
	 */
	if (gpio_pin_set(handle, pinn, pinv) < 0) {
		perror("gpio_pin_set");
		exit(1);
	}

	gpio_close(handle);
	exit(0);
}
예제 #23
0
static gboolean
on_boot(ControlHost *host,
		GDBusMethodInvocation *invocation,
		gpointer user_data)
{
	int rc = GPIO_OK;
	GDBusProxy *proxy;
	GError *error = NULL;
	GVariant *result = NULL;
	GDBusConnection *connection =
		g_dbus_object_manager_server_get_connection(manager);

	if(control_host_get_debug_mode(host)==1)
	{
		g_print("Enabling debug mode; not booting host\n");
		rc |= gpio_open(&fsi_enable);
		rc |= gpio_open(&cronus_sel);
		rc |= gpio_write(&fsi_enable,1);
		rc |= gpio_write(&cronus_sel,0);
		if(rc!=GPIO_OK) {
			g_print("ERROR enabling debug mode: %d\n",rc);
		}
		return TRUE;
	}
	g_print("Booting host\n");
	Control* control = object_get_control((Object*)user_data);
	control_host_complete_boot(host,invocation);
	do {
		rc = gpio_open(&fsi_clk);
		rc |= gpio_open(&fsi_data);
		rc |= gpio_open(&fsi_enable);
		rc |= gpio_open(&cronus_sel);
		rc |= gpio_open(&Throttle);
		rc |= gpio_open(&idbtn);
		if(rc!=GPIO_OK) { break; }

		//setup dc pins
		rc = gpio_write(&cronus_sel,1);
		rc |= gpio_write(&fsi_enable,1);
		rc |= gpio_write(&fsi_clk,1);
		rc |= gpio_write(&Throttle,1);
		rc |= gpio_write(&idbtn,0);
		if(rc!=GPIO_OK) { break; }

		//data standy state
		rc = fsi_standby();

		//clear out pipes
		rc |= gpio_write(&fsi_data,0);
		rc |= gpio_clock_cycle(&fsi_clk,256);
		rc |= gpio_write(&fsi_data,1);
		rc |= gpio_clock_cycle(&fsi_clk,50);
		if(rc!=GPIO_OK) { break; }

		rc = fsi_bitbang(attnA);
		rc |= fsi_standby();

		rc |= fsi_bitbang(attnB);
		rc |= fsi_standby();

		rc |= fsi_bitbang(attnC);
		rc |= fsi_standby();
		if(rc!=GPIO_OK) { break; }

		const gchar* flash_side = control_host_get_flash_side(host);
		g_print("Using %s side of the bios flash\n",flash_side);
		if(strcmp(flash_side,"primary")==0) {
			rc |= fsi_bitbang(primary);
		} else if(strcmp(flash_side,"golden") == 0) {
			rc |= fsi_bitbang(golden);
		} else {
			g_print("ERROR: Invalid flash side: %s\n",flash_side);
			rc = 0xff;

		}
		rc |= fsi_standby();
		if(rc!=GPIO_OK) { break; }

		rc = fsi_bitbang(go);

		rc |= gpio_write(&fsi_data,1); /* Data standby state */
		rc |= gpio_clock_cycle(&fsi_clk,2);

		rc |= gpio_write(&fsi_clk,0); /* hold clk low for clock mux */
		rc |= gpio_write(&fsi_enable,0);
		rc |= gpio_clock_cycle(&fsi_clk,16);
		rc |= gpio_write(&fsi_clk,0); /* Data standby state */

	} while(0);
	if(rc != GPIO_OK)
	{
		g_print("ERROR HostControl: GPIO sequence failed (rc=%d)\n",rc);
	} else {
		control_emit_goto_system_state(control,"HOST_BOOTING");
	}
	gpio_close(&fsi_clk);
	gpio_close(&fsi_data);
	gpio_close(&fsi_enable);
	gpio_close(&cronus_sel);
	gpio_close(&Throttle);
	gpio_close(&idbtn);

	// Start watchdog with 30s timeout per the OpenPower Host IPMI Spec.
	// Once the host starts booting, it'll reset and refresh the timer.
	error = NULL;
	proxy = g_dbus_proxy_new_sync(connection,
		G_DBUS_PROXY_FLAGS_NONE,
		NULL, /* GDBusInterfaceInfo* */
		"org.openbmc.watchdog.Host", /* name */
		"/org/openbmc/watchdog/host0", /* object path */
		"org.openbmc.Watchdog", /* interface name */
		NULL, /* GCancellable */
		&error);
	g_assert_no_error(error);
	if(error)
		goto exit;

	// Set watchdog timer to 30s
	error = NULL;
	result = g_dbus_proxy_call_sync(proxy,
		"set",
		g_variant_new("(i)", 30000),
		G_DBUS_CALL_FLAGS_NONE,
		-1,
		NULL,
		&error);
	g_assert_no_error(error);
	if (error)
		goto exit;
	if (result)
		g_variant_unref(result);

	// Start watchdog timer
	error = NULL;
	result = g_dbus_proxy_call_sync(proxy,
		"start",
		NULL,
		G_DBUS_CALL_FLAGS_NONE,
		-1,
		NULL,
		&error);
	g_assert_no_error(error);
	if (error)
		goto exit;

	control_host_emit_booted(host);

exit:
	if (result)
		g_variant_unref(result);

	return TRUE;
}
예제 #24
0
파일: main.c 프로젝트: nich2000/ncs
//==============================================================================
int main(int argc, char *argv[])
{
  //---------------------------------------------------------------------------
  #ifdef USE_PYTHON_APP
  exec_interactive_interpreter(argc, argv);
  #endif
  //---------------------------------------------------------------------------
  if(argc > 1)
  {
    if((strcmp(argv[1], CMD_S_VERSION) == 0) || ((strcmp(argv[1], CMD_VERSION) == 0)))
    {
      print_version();
      return 0;
    }
    if((strcmp(argv[1], CMD_S_HELP) == 0) || ((strcmp(argv[1], CMD_HELP) == 0)))
    {
      print_help(1);
      return 0;
    }
    if((strcmp(argv[1], CMD_S_CONFIG) == 0) || ((strcmp(argv[1], CMD_CONFIG) == 0)))
    {
      if(read_config() >= ERROR_WARNING)
        log_add_fmt(LOG_ERROR, "main,\nmessage: %s",
                    last_error()->message);
      print_config();
      return 0;
    }
  }
  //---------------------------------------------------------------------------
  print_version();
  //---------------------------------------------------------------------------
  if(read_config() >= LOG_ERROR)
    log_add_fmt(LOG_ERROR, "main,\nmessage: %s",
                last_error()->message);
  print_config();
  //---------------------------------------------------------------------------
  log_add(LOG_INFO, "application started");
  log_add(LOG_INFO, "-------------------");
  //---------------------------------------------------------------------------
  if(sock_init() >= ERROR_NORMAL)
    goto exit;
  //---------------------------------------------------------------------------
  #ifdef USE_PYTHON
  if(py_init() >= ERROR_NORMAL)
    goto exit;
  #endif
  //---------------------------------------------------------------------------
  #ifdef PI_DEVICE
  if(gpio_init() >= ERROR_NORMAL)
    goto exit;
  #endif
  //---------------------------------------------------------------------------
  char command[256];
  if(argc > 1)
  {
    // Read params
    for(int i = 1; i < argc; i++)
    {
      if((strcmp(argv[i], PARAM_S_PORT) == 0) || ((strcmp(argv[i], PARAM_PORT) == 0)))
      {
        cmd_server_port = atoi(argv[++i]);
      }
      else if((strcmp(argv[i], PARAM_S_WEB_PORT) == 0) || ((strcmp(argv[i], PARAM_WEB_PORT) == 0)))
      {
        web_server_port = atoi(argv[++i]);
      }
      else if((strcmp(argv[i], PARAM_S_WS_PORT) == 0) || ((strcmp(argv[i], PARAM_WS_PORT) == 0)))
      {
        ws_server_port = atoi(argv[++i]);
      }
      else if((strcmp(argv[i], PARAM_S_HOST) == 0) || ((strcmp(argv[i], PARAM_HOST) == 0)))
      {
        strcpy((char*)cmd_server_host, argv[++i]);
      }
      else if((strcmp(argv[i], PARAM_S_COUNT) == 0) || ((strcmp(argv[i], PARAM_COUNT) == 0)))
      {
        cmd_clients_count = atoi(argv[++i]);
      }
    }
    // Read cmd
    for(int i = 1; i < argc; i++)
    {
      if((strcmp(argv[i], CMD_S_ALL) == 0) || ((strcmp(argv[i], CMD_ALL) == 0)))
      {
        strcpy(command, CMD_ALL);
      }
      else if((strcmp(argv[i], CMD_S_SERVER) == 0) || ((strcmp(argv[i], CMD_SERVER) == 0)))
      {
        strcpy(command, CMD_SERVER);
      }
      else if((strcmp(argv[i], CMD_S_WEB_SERVER) == 0) || ((strcmp(argv[i], CMD_WEB_SERVER) == 0)))
      {
        strcpy(command, CMD_WEB_SERVER);
      }
      else if((strcmp(argv[i], CMD_S_WS_SERVER) == 0) || ((strcmp(argv[i], CMD_WS_SERVER) == 0)))
      {
        strcpy(command, CMD_WS_SERVER);
      }
      else if((strcmp(argv[i], CMD_S_CLIENT) == 0) || ((strcmp(argv[i], CMD_CLIENT) == 0)))
      {
        strcpy(command, CMD_CLIENT);
      }
    }

    handle_command_str(NULL, command);
  }
  //---------------------------------------------------------------------------
  if(history_load() >= ERROR_NORMAL)
    log_add_fmt(LOG_ERROR, "main,\nmessage: %s",
                last_error()->message);
  log_add(LOG_INFO, "command mode");
  //---------------------------------------------------------------------------
  strcpy(command, "\0");
  while(TRUE)
  {
//    char ch = getcode();
//    if(ch == '\033')
//    {
//      getchar(); // skip the [
//      ch = getchar();
//      switch(ch)
//      {
//        case 'A': // arrow up
//        {
//          strcpy(command, history_prev());
//          break;
//        }
//        case 'B': // arrow down
//        {
//          strcpy(command, history_next());
//          break;
//        }
//      }
//      if(strlen(command) != 0)
//      {
//        printf("%s\n", command);
//        continue;
//      }
//    }

//    if(strlen(command) == 0)
//    {
//      printf("manual input\n");
      fgets(command, sizeof(command), stdin);
      history_add(command);
//    };

    switch(handle_command_str(NULL, command))
    {
      case EXEC_NONE:
      {
        make_last_error(ERROR_NONE, errno, "exit by user command");
        goto exit;
      }
      case EXEC_UNKNOWN:
        log_add_fmt(LOG_CMD, "unknown command: %s",
                    command);
        break;
      case EXEC_DONE:
        log_add_fmt(LOG_CMD, "done command: %s",
                    command);
        break;
    }
    strcpy(command, "\0");
  }
  //---------------------------------------------------------------------------
  exit:
  sock_deinit();
  #ifdef PI_DEVICE
  gpio_close();
  #endif
  //---------------------------------------------------------------------------
  #ifdef USE_PYTHON
  py_final();
  #endif
  //---------------------------------------------------------------------------
  log_add_fmt(LOG_INFO, "application finished, result: %s\n", last_error()->message);
  //---------------------------------------------------------------------------
  return 0;
  //---------------------------------------------------------------------------
}
예제 #25
0
PyMODINIT_FUNC initGPIO(void)
#endif
{
   PyObject *module = NULL;

#if PY_MAJOR_VERSION > 2
   if ((module = PyModule_Create(&rpigpiomodule)) == NULL)
      goto exit;
#else
   if ((module = Py_InitModule("Ox.GPIO", rpi_gpio_methods)) == NULL)
      goto exit;
#endif

   WrongDirectionException = PyErr_NewException("Ox.GPIO.WrongDirectionException", NULL, NULL);
   PyModule_AddObject(module, "WrongDirectionException", WrongDirectionException);

   InvalidModeException = PyErr_NewException("Ox.GPIO.InvalidModeException", NULL, NULL);
   PyModule_AddObject(module, "InvalidModeException", InvalidModeException);

   InvalidDirectionException = PyErr_NewException("Ox.GPIO.InvalidDirectionException", NULL, NULL);
   PyModule_AddObject(module, "InvalidDirectionException", InvalidDirectionException);

   InvalidChannelException = PyErr_NewException("Ox.GPIO.InvalidChannelException", NULL, NULL);
   PyModule_AddObject(module, "InvalidChannelException", InvalidChannelException);

   InvalidPullException = PyErr_NewException("Ox.GPIO.InvalidPullException", NULL, NULL);
   PyModule_AddObject(module, "InvalidPullException", InvalidPullException);

   ModeNotSetException = PyErr_NewException("Ox.GPIO.ModeNotSetException", NULL, NULL);
   PyModule_AddObject(module, "ModeNotSetException", ModeNotSetException);

   SetupException = PyErr_NewException("Ox.GPIO.SetupException", NULL, NULL);
   PyModule_AddObject(module, "SetupException", SetupException);

   high = Py_BuildValue("i", HIGH);
   PyModule_AddObject(module, "HIGH", high);

   low = Py_BuildValue("i", LOW);
   PyModule_AddObject(module, "LOW", low);

   output = Py_BuildValue("i", OUTPUT);
   PyModule_AddObject(module, "OUT", output);

   input = Py_BuildValue("i", INPUT);
   PyModule_AddObject(module, "IN", input);
      
   version = Py_BuildValue("s", "0.4.1a");
   PyModule_AddObject(module, "VERSION", version);
   
   // set up mmaped areas
   if (module_setup() != SETUP_OK )
   {
#if PY_MAJOR_VERSION > 2
      return NULL;
#else
      return;
#endif
   }
      
   if (Py_AtExit(gpio_close) != 0)
   {
     gpio_close();
#if PY_MAJOR_VERSION > 2
      return NULL;
#else
      return;
#endif
   }

exit:
#if PY_MAJOR_VERSION > 2
   return module;
#else
   return;
#endif
}