aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2012-06-17 15:10:52 +0200
committerJakob Odersky <jodersky@gmail.com>2012-06-17 15:10:52 +0200
commit15708601c84dc12c6cf5409a7b03d2d87806d1a2 (patch)
tree99fd3638a20378f03bdde9b1d167085483e0f30b
parentef10a022de5bf32e7a7fd8e4830ce43266d10cd6 (diff)
downloadk8055-15708601c84dc12c6cf5409a7b03d2d87806d1a2.tar.gz
k8055-15708601c84dc12c6cf5409a7b03d2d87806d1a2.tar.bz2
k8055-15708601c84dc12c6cf5409a7b03d2d87806d1a2.zip
add ability to get currentr output status
-rw-r--r--src/k8055.c67
-rw-r--r--src/k8055.h46
2 files changed, 86 insertions, 27 deletions
diff --git a/src/k8055.c b/src/k8055.c
index 3a3daa8..92ff291 100644
--- a/src/k8055.c
+++ b/src/k8055.c
@@ -132,12 +132,14 @@
/** Represents a Vellemean K8055 USB board. */
struct k8055_device {
- /** Data last read from device, used by read_data(). */
+ /** Data last read from device, used by k8055_read_data(). */
unsigned char data_in[PACKET_LENGTH];
/** Data to be sent to the device, used by k8055_write_data(). */
unsigned char data_out[PACKET_LENGTH];
+ unsigned char current_out[PACKET_LENGTH];
+
/** Underlying libusb handle to device. NULL if the device is not open. */
libusb_device_handle *device_handle;
};
@@ -223,8 +225,21 @@ int k8055_open_device(int port, k8055_device** device) {
print_error("could not allocate memory for device");
return K8055_ERROR_MEM;
}
-
- (*_device).device_handle = handle;
+
+ _device->device_handle = handle; /* add usb handle */
+
+ for (int i = 0; i < PACKET_LENGTH; ++i) { /* initialize command data */
+ _device->data_out[i]=0;
+ _device->current_out[i]=0;
+ }
+
+ k8055_set_all_digital(_device, 0);
+ k8055_set_all_analog(_device, 0, 0);
+ k8055_set_debounce_time(_device, 0, 2);
+ k8055_set_debounce_time(_device, 1, 2);
+ k8055_reset_counter(_device, 1);
+ k8055_reset_counter(_device, 1);
+
*device = _device;
k8055_open_devices += 1;
@@ -267,13 +282,19 @@ static int k8055_write_data(k8055_device* device) {
print_error("could not write packet");
return K8055_ERROR_WRITE;
}
+
+ /* if there was no error up to this point, assume that data_out now reflects the devices output status */
+ for (int i = 0; i < PACKET_LENGTH; ++i) {
+ device->current_out[i]=device->data_out[i];
+ }
+
return 0;
}
/** Reads data from the usb endpoint into the device's data_in field.
* @return K8055_ERROR_CLOSED if the board is not open
* @return K8055_ERROR_READ if another error occurred during the read process */
-static int read_data(k8055_device* device, int cycles) {
+static int k8055_read_data(k8055_device* device, int cycles) {
int read_status = 0;
if (device->device_handle == NULL) {
@@ -298,7 +319,7 @@ static int read_data(k8055_device* device, int cycles) {
return 0;
}
-static int k8055_int_to_debounce(int t) {
+static unsigned char k8055_ms_to_char(int t) {
/* the velleman k8055 use a exponetial formula to split up the
DebounceTime 0-7450 over value 1-255. I've tested every value and
found that the formula dbt=0,338*value^1,8017 is closest to
@@ -306,9 +327,18 @@ static int k8055_int_to_debounce(int t) {
found the formula dbt=0,115*x^2 quite near the actual values, a
little below at really low values and a little above at really
high values. But the time set with this formula is within +-4% */
- if (t > 7450)
- t = 7450;
- t = sqrt(t / 0.115);
+
+ int c = t;
+
+ if (c > 7450)
+ c = 7450;
+ c = sqrt(c / 0.115);
+ if (c > ((int) c + 0.49999999)) /* simple round() function) */
+ c += 1;
+ return (unsigned char) c;
+}
+static int k8055_char_to_ms(unsigned char c) {
+ double t = 0.115 * c * c;
if (t > ((int) t + 0.49999999)) /* simple round() function) */
t += 1;
return t;
@@ -375,11 +405,11 @@ int k8055_reset_counter(k8055_device* device, int counter) {
int k8055_set_debounce_time(k8055_device* device, int counter, int debounce) {
if (counter == 0) {
- device->data_out[OUT_COUNTER_0_DEBOUNCE_OFFSET] = k8055_int_to_debounce(
+ device->data_out[OUT_COUNTER_0_DEBOUNCE_OFFSET] = k8055_ms_to_char(
debounce);
device->data_out[OUT_CMD_OFFEST] = CMD_SET_DEBOUNCE_1;
} else if (counter == 1) {
- device->data_out[OUT_COUNTER_1_DEBOUNCE_OFFSET] = k8055_int_to_debounce(
+ device->data_out[OUT_COUNTER_1_DEBOUNCE_OFFSET] = k8055_ms_to_char(
debounce);
device->data_out[OUT_CMD_OFFEST] = CMD_SET_DEBOUNCE_2;
} else {
@@ -395,7 +425,7 @@ int k8055_get_all_input(k8055_device* device, int *bitmask, int *analog0,
int cycles = 2;
if (quick)
cycles = 1;
- int r = read_data(device, cycles);
+ int r = k8055_read_data(device, cycles);
if (r != 0)
return r;
@@ -415,3 +445,18 @@ int k8055_get_all_input(k8055_device* device, int *bitmask, int *analog0,
| device->data_in[IN_COUNTER_1_OFFSET];
return 0;
}
+
+void k8055_get_all_output(k8055_device* device, int* bitmask, int *analog0,
+ int *analog1, int *debounce0, int *debounce1) {
+
+ if (bitmask != NULL)
+ *bitmask = device->current_out[OUT_DIGITAL_OFFSET];
+ if (analog0 != NULL)
+ *analog0 = device->current_out[OUT_ANALOG_0_OFFSET];
+ if (analog1 != NULL)
+ *analog1 = device->current_out[OUT_ANALOG_1_OFFSET];
+ if (debounce0 != NULL)
+ *debounce0 = k8055_char_to_ms(device->current_out[OUT_COUNTER_0_DEBOUNCE_OFFSET]);
+ if (debounce1 != NULL)
+ *debounce1 = k8055_char_to_ms(device->current_out[OUT_COUNTER_1_DEBOUNCE_OFFSET]);
+}
diff --git a/src/k8055.h b/src/k8055.h
index 75f379c..5154214 100644
--- a/src/k8055.h
+++ b/src/k8055.h
@@ -61,70 +61,84 @@ enum k8055_error_code {
int k8055_open_device(int port, k8055_device** device);
/** Closes the given device. */
-void k8055_close_device(k8055_device* port);
+void k8055_close_device(k8055_device* device);
/**Sets all digital ouputs according to the given bitmask.
- * @param port address of board
+ * @param device k8055 board
* @param bitmask '1' for 'on', '0' for 'off'
* @return K8055_ERROR_CLOSED if the given device is not open
* @return K8055_ERROR_WRITE if another error occurred during the write process */
-int k8055_set_all_digital(k8055_device*, int bitmask);
+int k8055_set_all_digital(k8055_device* device, int bitmask);
/**Sets a digital output at given channel.
- * @param port address of board
+ * @param device k8055 board
* @param channel channel of port
* @param value output status: '1' for 'on', '0' for 'off'
* @return K8055_ERROR_CLOSED if the given device is not open
* @return K8055_ERROR_WRITE if another error occurred during the write process */
-int k8055_set_digital(k8055_device*, int channel, int value);
+int k8055_set_digital(k8055_device* device, int channel, int value);
/**Sets the values of both analog outputs.
- * @param port address of board
+ * @param device k8055 board
* @param analog0 value of first analog output
* @param analog1 value of second analog output
* @return K8055_ERROR_CLOSED if the given device is not open
* @return K8055_ERROR_WRITE if another error occurred during the write process */
-int k8055_set_all_analog(k8055_device*, int analog0, int analog1);
+int k8055_set_all_analog(k8055_device* device, int analog0, int analog1);
/**Sets the value for an analog output at a given channel.
- * @param port address of board
+ * @param device k8055 board
* @param channel channel of analog output (zero indexed)
* @param value value of analog output [0-255]
* @return K8055_ERROR_INDEX if channel is an invalid index
* @return K8055_ERROR_CLOSED if the given device is not open
* @return K8055_ERROR_WRITE if another error occurred during the write process */
-int k8055_set_analog(k8055_device*, int channel, int value);
+int k8055_set_analog(k8055_device* device, int channel, int value);
/**Resets a hardware integrated counter of the Velleman K8055 board.
- * @param port address of board
+ * @param device k8055 board
* @param counter index of counter (zero indexed)
* @return K8055_ERROR_INDEX if counter is an invalid index
* @return K8055_ERROR_CLOSED if the given device is not open
* @return K8055_ERROR_WRITE if another error occurred during the write process */
-int k8055_reset_counter(k8055_device*, int counter);
+int k8055_reset_counter(k8055_device* device, int counter);
/**Sets the debounce time of a hardware integrated counter of the Velleman K8055 board.
- * @param port address of board
+ * @param device k8055 board
* @param counter index of counter (zero indexed)
* @param debounce debounce value
* @return K8055_ERROR_INDEX if counter is an invalid index
* @return K8055_ERROR_CLOSED if the given device is not open
* @return K8055_ERROR_WRITE if another error occurred during the write process*/
-int k8055_set_debounce_time(k8055_device*, int counter, int debounce);
+int k8055_set_debounce_time(k8055_device* device, int counter, int debounce);
/**Reads all current data of a given board into the passed parameters. NULL is a valid parameter.
* Unless quick is set, data is read twice from the board to circumvent some kind of buffer and get current data.
- * @param port address of board
- * @param digitalBitmask bitmask value of digital inputs
+ * @param device k8055 board
+ * @param digitalBitmask bitmask value of digital inputs (there are 5 digital inputs)
* @param analog0 value of first analog input
* @param analog1 value of second analog input
* @param counter0 value of first counter
* @param counter1 value of second counter
+ * @param quick if set, read data only once
* @return 0 on success
* @return K8055_ERROR_CLOSED if the given device is not open
* @return K8055_ERROR_READ if another error occurred during the read process */
-int k8055_get_all_input(k8055_device*, int *digitalBitmask, int *analog0,
+int k8055_get_all_input(k8055_device* device, int *digitalBitmask, int *analog0,
int *analog1, int *counter0, int *counter1, bool quick);
+
+/**Gets a given board's current output status. NULL is a valid parameter.
+ * Note: as the K8055's firmware does not provide any method for querying the board's output status,
+ * this library only tracks the board's status by recording any successfull data writes.
+ * Hence no guarantee can be given on the validity of the output status.
+ * @param device k8055 board
+ * @param digitalBitmask bitmask value of digital outputs (there are 8 digital outputs)
+ * @param analog0 value of first analog output
+ * @param analog1 value of second analog output
+ * @param debounce0 value of first counter's debounce time [ms]
+ * @param debounce1 value of second counter's debounce time [ms] */
+void k8055_get_all_output(k8055_device* device, int* digitalBitmask, int *analog0,
+ int *analog1, int *debounce0, int *debounce1);
#ifdef __cplusplus
}