⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xbee_gpio_client.c

📁 Dynamic C 程式語言源碼 嵌入式控制系統 Xbee蜂群網路~
💻 C
📖 第 1 页 / 共 4 页
字号:
			if (resp->length & 0x80) {
				range = (xbee_gpio_rec_ar_resp_range_t *) &data[record_len];
				record_len += 8;
			} else {
				range = NULL;
			}
			if (record_len > datalen) {
#ifdef GPIO_VERBOSE
				printf("  %s(%3d): decode error, record (%d) too long for" \
					" remaining payload (%d)\n", gpio_signal[resp->signal].name,
                  resp->signal, record_len, datalen);
#endif
				return;
			}
#ifdef GPIO_VERBOSE
			if (resp->length & 0x70) {
				printf("  %s(%3d): warning, extra flags set: 0x%02x\n",
				 gpio_signal[resp->signal].name, resp->signal, resp->length & 0x70);
			}
#endif

         memcpy(units, resp->units, units_len);
         units[units_len] = '\0';
         if (range) {
	         printf("  %s range: %.3f to %.3f, units=[%s]\n",
              gpio_signal[resp->signal].name, range->lower, range->upper,
              units);
         } else {
	         printf("  %s(%3d): no range, units=[%s]\n",
                      gpio_signal[resp->signal].name, resp->signal, units);
			}
         datalen -= record_len;
         data += record_len;
         if (gpio_device[gpio_index].ep_count) {
            gpio_device[gpio_index].ep_count--;
         }
		}
	}

#ifdef GPIO_VERBOSE
   if (datalen)
   {
      printf("  bad packet, 1 extra byte at end (0x%02x)\n", *data);
   }
#endif
   if (gpio_device[gpio_index].ep_count) {
      gpio_device[gpio_index].state = CLIENT_STATE_REQ_ANARANGE;
   }
}

int request_gpio_read(int node_index, int io_start, int io_end)
{
   int rc;

   rc = request_gpio_iorange(node_index, XBEE_GPIO_CLUST_READ, io_start,
		                         io_end);
   if (!rc) {
	   gpio_device[gpio_index].state = CLIENT_STATE_PARSE_READ;
	   gpio_device[gpio_index].last_ep = io_end;
	   gpio_device[gpio_index].ep_count = io_end - io_start + 1;
   }
	return rc;
}

typedef struct {
	byte	signal;
	byte	type;
	union {
		byte		digital;
		float		analog;
	} value;
} xbee_gpio_rec_read_response_t;

void xbeeGpioReadResp(char *data, int datalen)
{
	xbee_gpio_rec_read_response_t *resp;
	int record_len;
   char digital, buf[32];

#ifdef GPIO_VERBOSE
	printf("parsing read response\n");
	xb_hexdump(data, datalen);
#endif

	while (datalen >= 2) {
      digital = 0;
		resp = (xbee_gpio_rec_read_response_t *) data;
      switch (resp->type) {
         case XBEE_GPIO_TYPE_DISABLED:
            printf("  %s: disabled\n", gpio_signal[resp->signal].name);
            record_len = 2;
            break;

         case XBEE_GPIO_TYPE_INVALID:
            printf("  %s: invalid\n", gpio_signal[resp->signal].name);
            record_len = 2;
            break;

         case XBEE_GPIO_TYPE_SWITCH_IN:
            strcpy(buf, "Switch Input, value = ");
            strcpy(buf + 22, (resp->value.digital ? "CLOSED" : "OPEN"));
            digital = 1;
            break;

         case XBEE_GPIO_TYPE_LED_OUT:
            strcpy(buf, "LED Output, value = ");
            strcpy(buf + 20, (resp->value.digital ? "ON" : "OFF"));
            digital = 1;
            break;

         case XBEE_GPIO_TYPE_DIGITAL_OUT:
         case XBEE_GPIO_TYPE_DIGITAL_IN:
            strcpy(buf, (resp->type == XBEE_GPIO_TYPE_DIGITAL_IN ?
                    "Digital Input,  value = " : "Digital Output, value = "));
            strcpy(buf + 24, (resp->value.digital ? "HIGH" : "LOW"));
            digital = 1;
            break;

         case XBEE_GPIO_TYPE_SINK_OUT:
            strcpy(buf, "Sinking Output, value = ");
            strcpy(buf + 24, (resp->value.digital ? "TRI" : "LOW"));
            digital = 1;
            break;

         case XBEE_GPIO_TYPE_SOURCE_OUT:
            strcpy(buf, "Source Output, value = ");
            strcpy(buf + 23, (resp->value.digital == 1 ? "HIGH" : "TRI"));
            digital = 1;
            break;

         case XBEE_GPIO_TYPE_TRISTATE_OUT:
            strcpy(buf, "Tri-State Output, value = ");
            strcpy(buf + 26, (resp->value.digital ? (resp->value.digital == 1 ?
                    "HIGH" : "TRI") : "LOW"));
            digital = 1;
            break;

         case XBEE_GPIO_TYPE_ANALOG_OUT:
         case XBEE_GPIO_TYPE_ANALOG_IN:
         	record_len = 6;
         	if (datalen < record_len) {
					printf("  %s: error, record to short\n",
                        gpio_signal[resp->signal].name);
					return;
         	}
         	printf("  %s: type Analog %s, value = %.3f\n",
                gpio_signal[resp->signal].name,
                (resp->type == XBEE_GPIO_TYPE_ANALOG_IN ? "In" : "Out"),
                resp->value.analog);
				break;

         default:
            printf("  %s: unknown type 0x%02x, rest of packet ignored\n",
               gpio_signal[resp->signal].name, resp->type);
            return;
      }
      if (digital) {
         record_len = 3;
         if (datalen < record_len) {
            printf("  %s: error, record to short\n",
                        gpio_signal[resp->signal].name);
            return;
         }
         printf("  %s: type %s\n", gpio_signal[resp->signal].name, buf);
      }
      datalen -= record_len;
      data += record_len;
      if (gpio_device[gpio_index].ep_count)
      {
         gpio_device[gpio_index].ep_count--;
      }
	}

   if (datalen)
   {
      printf("  bad packet, 1 extra byte at end (0x%02x)\n", *data);
   }
   if (gpio_device[gpio_index].ep_count) {
      gpio_device[gpio_index].state = CLIENT_STATE_REQ_READ;
   }
}

typedef struct {
	byte	length;
	byte	payload[XBEE_MAX_RFPAYLOAD];
} xbee_payload_t;

void xbee_payload_clear(xbee_payload_t *fp)
{
	memset(fp, 0, sizeof(*fp));
}

int request_gpio_write(int node_index, xbee_payload_t *fp)
{
	int err;

   gpio_device[gpio_index].state = CLIENT_STATE_PARSE_WRITE;
   gpio_device[gpio_index].ep_count = 1;

	err = request_gpio(node_index, XBEE_GPIO_CLUST_WRITE, fp->payload,
		(int) fp->length);

	if (err)
   {
      printf("error %d sending write request\n", err);
   }

	return err;
}

int request_gpio_append_int(xbee_payload_t *fp, int signal, int type,
	int value)
{
	char *p;

	// make sure there's enough room in the payload
	if (fp->length + 3 > XBEE_MAX_RFPAYLOAD) return -1;

	p = &fp->payload[fp->length];
	*p++ = signal;
	*p++ = type;
	*p = value;
	fp->length += 3;

	return 0;
}

int request_gpio_append_float(xbee_payload_t *fp, int signal, int type,
	float value)
{
	char *p;

	// make sure there's enough room in the payload
	if (fp->length + 6 > XBEE_MAX_RFPAYLOAD) return -1;

	p = &fp->payload[fp->length];
	*p++ = signal;
	*p++ = type;
	memcpy(p, &value, 4);
	fp->length += 6;

	return 0;
}

void xbeeGpioWriteResp(char *data, int datalen)
{
	char *status;
	char buffer[20];

#ifdef GPIO_VERBOSE
	printf("parsing write response\n");
	xb_hexdump(data, datalen);
#endif
   // data[0] is the signal index, data[1] is the signal status
	while (datalen >= 2) {
		switch (data[1]) {
			case XBEE_GPIO_STATUS_SUCCESS:
				status = "success";
				break;

			case XBEE_GPIO_STATUS_DISABLED:
				status = "failed, I/O is disabled";
				break;

			case XBEE_GPIO_STATUS_BAD_TYPE:
				status = "failed, wrong I/O type";
				break;

			case XBEE_GPIO_STATUS_OUT_OF_RANGE:
				status = "failed, out of analog range";
				break;

			case XBEE_GPIO_STATUS_INVALID:
				status = "failed, invalid I/O signal";
				break;

			default:
				sprintf(buffer, "unknown error 0x%02x", data[1]);
				status = buffer;
		}
      gpio_device[gpio_index].ep_count = 0;
      printf("  %s: %s\n", gpio_signal[data[0]].name, status);
		data += 2;
		datalen -= 2;
	}
   if (datalen)
   {
      printf("  bad packet, 1 extra byte at end (0x%02x)\n", *data);
   }
}

void gpio_write_digital(int node_index, int signal, int value)
{
	xbee_payload_t zp;

	xbee_payload_clear(&zp);
	request_gpio_append_int(&zp, signal, gpio_signal[signal].type, value);

	request_gpio_write(node_index, &zp);
}

void gpio_write_analog(int node_index, int signal, float value)
{
	xbee_payload_t zp;

	xbee_payload_clear(&zp);
	request_gpio_append_float(&zp, signal, XBEE_GPIO_TYPE_ANALOG_OUT, value);

	request_gpio_write(node_index, &zp);
}

int gpio_open_node(int node)
{
   if ((gpio_device[node].io_count) && (gpio_device[node].node_index >= 0)) {
      gpio_index = node;
      gpio_device[node].state = CLIENT_STATE_NEW_NAME;
      printf("\n\nGPIO server %d opened\n\n", node);
	   return ZB_NODE_OPEN;
   }
   else {
      return ZB_IDLE;
   }
}

void gpio_help(int flags)
{
   int i, analog;

   if (flags & SHOW_NET_HELP) {
	   printf("\nValid Network Commands\n");
	   printf("-------------------------------------\n");
	   printf("D         Discover new nodes on the network and scan\n");
      if (gpio_last) {
   	  printf("N         List available GPIO servers on discovered nodes\n");
   	  printf("0 - %d     Attach to the specified GPIO server\n", gpio_last-1);
      }
      printf("H         Show this help menu\n");
      printf("X         Exit the GPIO client program\n\nN> ");
   }
   if (flags & SHOW_SIGNALS) {
	   printf("GPIO Signals\n-------------------------------------\n");
      for (i = analog = 0; i < gpio_device[gpio_index].io_count; i++)
      {
         // Print out names of signals on GPIO server
         printf(" %3d) %s is ", i, gpio_signal[i].name);
         switch (gpio_signal[i].type) {
            case XBEE_GPIO_TYPE_ANALOG_IN:
               analog = 1;
               printf("an analog input.\n");
               break;
            case XBEE_GPIO_TYPE_DIGITAL_IN:
               printf("a digital input\n");
               break;
            case XBEE_GPIO_TYPE_SWITCH_IN:
               printf("a switch input\n");
               break;
            case XBEE_GPIO_TYPE_ANALOG_OUT:
               printf("an analog output.\n");
               break;
            case XBEE_GPIO_TYPE_DIGITAL_OUT:
               printf("a digital output\n");
               break;
            case XBEE_GPIO_TYPE_LED_OUT:
               printf("an LED output\n");
               break;
            case XBEE_GPIO_TYPE_SINK_OUT:
               printf("a sinking output\n");
               break;
            case XBEE_GPIO_TYPE_SOURCE_OUT:
               printf("a sourcing output\n");
               break;
            case XBEE_GPIO_TYPE_TRISTATE_OUT:
               printf("a tri-state output\n");
               break;
            default:
               printf("an unknown signal\n");
               break;
         }
      }
      if (analog) {
	      printf("\n  Analog Ranges\n-----------------\n");
	      gpio_device[gpio_index].state = CLIENT_STATE_REQ_ANARANGE;
         return;   // Don't allow help now if analog inputs are present
      }
   }
   if (flags & SHOW_GPIO_HELP) {
	   printf("\nValid GPIO Commands\n-------------------------------------\n");
	   printf("GET ALL         Get values from all signals\n");
	   printf("GET name        Get value from named signal\n");
	   printf("SET name value  Set value of named signal\n");
      printf("         (If digital: value can be LOW, HI, TRI, ON or OFF)\n");
	   printf("CLOSE           Close the GPIO device - Back to Network menu\n");
      printf("NAMES           Show signal names for the current GPIO device\n");
	   printf("HELP            Show this menu\n\nG> ");
   }
}

#define PARSE_MAX_BUF 128    // Maximum command string size

int parse_cmd(int ch)
{
   static char buf[PARSE_MAX_BUF + 1];
   static char * ptr;
   int state, i, cmd, signal, value, type, max;
   float fp_value;
   char *end;

   if (ch < 0)
   {
      // Clear command string buffer
      ptr = buf;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -