00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #define IPCON_EXPOSE_INTERNALS
00013
00014 #include "bricklet_industrial_digital_in_4.h"
00015
00016 #include <string.h>
00017
00018 #ifdef __cplusplus
00019 extern "C" {
00020 #endif
00021
00022
00023
00024 typedef void (*InterruptCallbackFunction)(uint16_t, uint16_t, void *);
00025
00026 #if defined _MSC_VER || defined __BORLANDC__
00027 #pragma pack(push)
00028 #pragma pack(1)
00029 #define ATTRIBUTE_PACKED
00030 #elif defined __GNUC__
00031 #ifdef _WIN32
00032
00033
00034 #define ATTRIBUTE_PACKED __attribute__((gcc_struct, packed))
00035 #else
00036 #define ATTRIBUTE_PACKED __attribute__((packed))
00037 #endif
00038 #else
00039 #error unknown compiler, do not know how to enable struct packing
00040 #endif
00041
00042 typedef struct {
00043 PacketHeader header;
00044 } ATTRIBUTE_PACKED GetValue_;
00045
00046 typedef struct {
00047 PacketHeader header;
00048 uint16_t value_mask;
00049 } ATTRIBUTE_PACKED GetValueResponse_;
00050
00051 typedef struct {
00052 PacketHeader header;
00053 char group[4];
00054 } ATTRIBUTE_PACKED SetGroup_;
00055
00056 typedef struct {
00057 PacketHeader header;
00058 } ATTRIBUTE_PACKED GetGroup_;
00059
00060 typedef struct {
00061 PacketHeader header;
00062 char group[4];
00063 } ATTRIBUTE_PACKED GetGroupResponse_;
00064
00065 typedef struct {
00066 PacketHeader header;
00067 } ATTRIBUTE_PACKED GetAvailableForGroup_;
00068
00069 typedef struct {
00070 PacketHeader header;
00071 uint8_t available;
00072 } ATTRIBUTE_PACKED GetAvailableForGroupResponse_;
00073
00074 typedef struct {
00075 PacketHeader header;
00076 uint32_t debounce;
00077 } ATTRIBUTE_PACKED SetDebouncePeriod_;
00078
00079 typedef struct {
00080 PacketHeader header;
00081 } ATTRIBUTE_PACKED GetDebouncePeriod_;
00082
00083 typedef struct {
00084 PacketHeader header;
00085 uint32_t debounce;
00086 } ATTRIBUTE_PACKED GetDebouncePeriodResponse_;
00087
00088 typedef struct {
00089 PacketHeader header;
00090 uint16_t interrupt_mask;
00091 } ATTRIBUTE_PACKED SetInterrupt_;
00092
00093 typedef struct {
00094 PacketHeader header;
00095 } ATTRIBUTE_PACKED GetInterrupt_;
00096
00097 typedef struct {
00098 PacketHeader header;
00099 uint16_t interrupt_mask;
00100 } ATTRIBUTE_PACKED GetInterruptResponse_;
00101
00102 typedef struct {
00103 PacketHeader header;
00104 uint16_t interrupt_mask;
00105 uint16_t value_mask;
00106 } ATTRIBUTE_PACKED InterruptCallback_;
00107
00108 typedef struct {
00109 PacketHeader header;
00110 uint8_t pin;
00111 bool reset_counter;
00112 } ATTRIBUTE_PACKED GetEdgeCount_;
00113
00114 typedef struct {
00115 PacketHeader header;
00116 uint32_t count;
00117 } ATTRIBUTE_PACKED GetEdgeCountResponse_;
00118
00119 typedef struct {
00120 PacketHeader header;
00121 uint16_t selection_mask;
00122 uint8_t edge_type;
00123 uint8_t debounce;
00124 } ATTRIBUTE_PACKED SetEdgeCountConfig_;
00125
00126 typedef struct {
00127 PacketHeader header;
00128 uint8_t pin;
00129 } ATTRIBUTE_PACKED GetEdgeCountConfig_;
00130
00131 typedef struct {
00132 PacketHeader header;
00133 uint8_t edge_type;
00134 uint8_t debounce;
00135 } ATTRIBUTE_PACKED GetEdgeCountConfigResponse_;
00136
00137 typedef struct {
00138 PacketHeader header;
00139 } ATTRIBUTE_PACKED GetIdentity_;
00140
00141 typedef struct {
00142 PacketHeader header;
00143 char uid[8];
00144 char connected_uid[8];
00145 char position;
00146 uint8_t hardware_version[3];
00147 uint8_t firmware_version[3];
00148 uint16_t device_identifier;
00149 } ATTRIBUTE_PACKED GetIdentityResponse_;
00150
00151 #if defined _MSC_VER || defined __BORLANDC__
00152 #pragma pack(pop)
00153 #endif
00154 #undef ATTRIBUTE_PACKED
00155
00156 static void industrial_digital_in_4_callback_wrapper_interrupt(DevicePrivate *device_p, Packet *packet) {
00157 InterruptCallbackFunction callback_function;
00158 void *user_data = device_p->registered_callback_user_data[INDUSTRIAL_DIGITAL_IN_4_CALLBACK_INTERRUPT];
00159 InterruptCallback_ *callback = (InterruptCallback_ *)packet;
00160 *(void **)(&callback_function) = device_p->registered_callbacks[INDUSTRIAL_DIGITAL_IN_4_CALLBACK_INTERRUPT];
00161
00162 if (callback_function == NULL) {
00163 return;
00164 }
00165
00166 callback->interrupt_mask = leconvert_uint16_from(callback->interrupt_mask);
00167 callback->value_mask = leconvert_uint16_from(callback->value_mask);
00168
00169 callback_function(callback->interrupt_mask, callback->value_mask, user_data);
00170 }
00171
00172 void industrial_digital_in_4_create(IndustrialDigitalIn4 *industrial_digital_in_4, const char *uid, IPConnection *ipcon) {
00173 DevicePrivate *device_p;
00174
00175 device_create(industrial_digital_in_4, uid, ipcon->p, 2, 0, 1);
00176
00177 device_p = industrial_digital_in_4->p;
00178
00179 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_VALUE] = DEVICE_RESPONSE_EXPECTED_ALWAYS_TRUE;
00180 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_FUNCTION_SET_GROUP] = DEVICE_RESPONSE_EXPECTED_FALSE;
00181 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_GROUP] = DEVICE_RESPONSE_EXPECTED_ALWAYS_TRUE;
00182 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_AVAILABLE_FOR_GROUP] = DEVICE_RESPONSE_EXPECTED_ALWAYS_TRUE;
00183 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_FUNCTION_SET_DEBOUNCE_PERIOD] = DEVICE_RESPONSE_EXPECTED_TRUE;
00184 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_DEBOUNCE_PERIOD] = DEVICE_RESPONSE_EXPECTED_ALWAYS_TRUE;
00185 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_FUNCTION_SET_INTERRUPT] = DEVICE_RESPONSE_EXPECTED_TRUE;
00186 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_INTERRUPT] = DEVICE_RESPONSE_EXPECTED_ALWAYS_TRUE;
00187 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_CALLBACK_INTERRUPT] = DEVICE_RESPONSE_EXPECTED_ALWAYS_FALSE;
00188 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_EDGE_COUNT] = DEVICE_RESPONSE_EXPECTED_ALWAYS_TRUE;
00189 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_FUNCTION_SET_EDGE_COUNT_CONFIG] = DEVICE_RESPONSE_EXPECTED_FALSE;
00190 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_EDGE_COUNT_CONFIG] = DEVICE_RESPONSE_EXPECTED_ALWAYS_TRUE;
00191 device_p->response_expected[INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_IDENTITY] = DEVICE_RESPONSE_EXPECTED_ALWAYS_TRUE;
00192
00193 device_p->callback_wrappers[INDUSTRIAL_DIGITAL_IN_4_CALLBACK_INTERRUPT] = industrial_digital_in_4_callback_wrapper_interrupt;
00194 }
00195
00196 void industrial_digital_in_4_destroy(IndustrialDigitalIn4 *industrial_digital_in_4) {
00197 device_release(industrial_digital_in_4->p);
00198 }
00199
00200 int industrial_digital_in_4_get_response_expected(IndustrialDigitalIn4 *industrial_digital_in_4, uint8_t function_id, bool *ret_response_expected) {
00201 return device_get_response_expected(industrial_digital_in_4->p, function_id, ret_response_expected);
00202 }
00203
00204 int industrial_digital_in_4_set_response_expected(IndustrialDigitalIn4 *industrial_digital_in_4, uint8_t function_id, bool response_expected) {
00205 return device_set_response_expected(industrial_digital_in_4->p, function_id, response_expected);
00206 }
00207
00208 int industrial_digital_in_4_set_response_expected_all(IndustrialDigitalIn4 *industrial_digital_in_4, bool response_expected) {
00209 return device_set_response_expected_all(industrial_digital_in_4->p, response_expected);
00210 }
00211
00212 void industrial_digital_in_4_register_callback(IndustrialDigitalIn4 *industrial_digital_in_4, uint8_t id, void *callback, void *user_data) {
00213 device_register_callback(industrial_digital_in_4->p, id, callback, user_data);
00214 }
00215
00216 int industrial_digital_in_4_get_api_version(IndustrialDigitalIn4 *industrial_digital_in_4, uint8_t ret_api_version[3]) {
00217 return device_get_api_version(industrial_digital_in_4->p, ret_api_version);
00218 }
00219
00220 int industrial_digital_in_4_get_value(IndustrialDigitalIn4 *industrial_digital_in_4, uint16_t *ret_value_mask) {
00221 DevicePrivate *device_p = industrial_digital_in_4->p;
00222 GetValue_ request;
00223 GetValueResponse_ response;
00224 int ret;
00225
00226 ret = packet_header_create(&request.header, sizeof(request), INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_VALUE, device_p->ipcon_p, device_p);
00227
00228 if (ret < 0) {
00229 return ret;
00230 }
00231
00232
00233 ret = device_send_request(device_p, (Packet *)&request, (Packet *)&response);
00234
00235 if (ret < 0) {
00236 return ret;
00237 }
00238 *ret_value_mask = leconvert_uint16_from(response.value_mask);
00239
00240
00241
00242 return ret;
00243 }
00244
00245 int industrial_digital_in_4_set_group(IndustrialDigitalIn4 *industrial_digital_in_4, char group[4]) {
00246 DevicePrivate *device_p = industrial_digital_in_4->p;
00247 SetGroup_ request;
00248 int ret;
00249
00250 ret = packet_header_create(&request.header, sizeof(request), INDUSTRIAL_DIGITAL_IN_4_FUNCTION_SET_GROUP, device_p->ipcon_p, device_p);
00251
00252 if (ret < 0) {
00253 return ret;
00254 }
00255
00256 memcpy(request.group, group, 4 * sizeof(char));
00257
00258 ret = device_send_request(device_p, (Packet *)&request, NULL);
00259
00260
00261 return ret;
00262 }
00263
00264 int industrial_digital_in_4_get_group(IndustrialDigitalIn4 *industrial_digital_in_4, char ret_group[4]) {
00265 DevicePrivate *device_p = industrial_digital_in_4->p;
00266 GetGroup_ request;
00267 GetGroupResponse_ response;
00268 int ret;
00269
00270 ret = packet_header_create(&request.header, sizeof(request), INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_GROUP, device_p->ipcon_p, device_p);
00271
00272 if (ret < 0) {
00273 return ret;
00274 }
00275
00276
00277 ret = device_send_request(device_p, (Packet *)&request, (Packet *)&response);
00278
00279 if (ret < 0) {
00280 return ret;
00281 }
00282 memcpy(ret_group, response.group, 4 * sizeof(char));
00283
00284
00285
00286 return ret;
00287 }
00288
00289 int industrial_digital_in_4_get_available_for_group(IndustrialDigitalIn4 *industrial_digital_in_4, uint8_t *ret_available) {
00290 DevicePrivate *device_p = industrial_digital_in_4->p;
00291 GetAvailableForGroup_ request;
00292 GetAvailableForGroupResponse_ response;
00293 int ret;
00294
00295 ret = packet_header_create(&request.header, sizeof(request), INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_AVAILABLE_FOR_GROUP, device_p->ipcon_p, device_p);
00296
00297 if (ret < 0) {
00298 return ret;
00299 }
00300
00301
00302 ret = device_send_request(device_p, (Packet *)&request, (Packet *)&response);
00303
00304 if (ret < 0) {
00305 return ret;
00306 }
00307 *ret_available = response.available;
00308
00309
00310
00311 return ret;
00312 }
00313
00314 int industrial_digital_in_4_set_debounce_period(IndustrialDigitalIn4 *industrial_digital_in_4, uint32_t debounce) {
00315 DevicePrivate *device_p = industrial_digital_in_4->p;
00316 SetDebouncePeriod_ request;
00317 int ret;
00318
00319 ret = packet_header_create(&request.header, sizeof(request), INDUSTRIAL_DIGITAL_IN_4_FUNCTION_SET_DEBOUNCE_PERIOD, device_p->ipcon_p, device_p);
00320
00321 if (ret < 0) {
00322 return ret;
00323 }
00324
00325 request.debounce = leconvert_uint32_to(debounce);
00326
00327 ret = device_send_request(device_p, (Packet *)&request, NULL);
00328
00329
00330 return ret;
00331 }
00332
00333 int industrial_digital_in_4_get_debounce_period(IndustrialDigitalIn4 *industrial_digital_in_4, uint32_t *ret_debounce) {
00334 DevicePrivate *device_p = industrial_digital_in_4->p;
00335 GetDebouncePeriod_ request;
00336 GetDebouncePeriodResponse_ response;
00337 int ret;
00338
00339 ret = packet_header_create(&request.header, sizeof(request), INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_DEBOUNCE_PERIOD, device_p->ipcon_p, device_p);
00340
00341 if (ret < 0) {
00342 return ret;
00343 }
00344
00345
00346 ret = device_send_request(device_p, (Packet *)&request, (Packet *)&response);
00347
00348 if (ret < 0) {
00349 return ret;
00350 }
00351 *ret_debounce = leconvert_uint32_from(response.debounce);
00352
00353
00354
00355 return ret;
00356 }
00357
00358 int industrial_digital_in_4_set_interrupt(IndustrialDigitalIn4 *industrial_digital_in_4, uint16_t interrupt_mask) {
00359 DevicePrivate *device_p = industrial_digital_in_4->p;
00360 SetInterrupt_ request;
00361 int ret;
00362
00363 ret = packet_header_create(&request.header, sizeof(request), INDUSTRIAL_DIGITAL_IN_4_FUNCTION_SET_INTERRUPT, device_p->ipcon_p, device_p);
00364
00365 if (ret < 0) {
00366 return ret;
00367 }
00368
00369 request.interrupt_mask = leconvert_uint16_to(interrupt_mask);
00370
00371 ret = device_send_request(device_p, (Packet *)&request, NULL);
00372
00373
00374 return ret;
00375 }
00376
00377 int industrial_digital_in_4_get_interrupt(IndustrialDigitalIn4 *industrial_digital_in_4, uint16_t *ret_interrupt_mask) {
00378 DevicePrivate *device_p = industrial_digital_in_4->p;
00379 GetInterrupt_ request;
00380 GetInterruptResponse_ response;
00381 int ret;
00382
00383 ret = packet_header_create(&request.header, sizeof(request), INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_INTERRUPT, device_p->ipcon_p, device_p);
00384
00385 if (ret < 0) {
00386 return ret;
00387 }
00388
00389
00390 ret = device_send_request(device_p, (Packet *)&request, (Packet *)&response);
00391
00392 if (ret < 0) {
00393 return ret;
00394 }
00395 *ret_interrupt_mask = leconvert_uint16_from(response.interrupt_mask);
00396
00397
00398
00399 return ret;
00400 }
00401
00402 int industrial_digital_in_4_get_edge_count(IndustrialDigitalIn4 *industrial_digital_in_4, uint8_t pin, bool reset_counter, uint32_t *ret_count) {
00403 DevicePrivate *device_p = industrial_digital_in_4->p;
00404 GetEdgeCount_ request;
00405 GetEdgeCountResponse_ response;
00406 int ret;
00407
00408 ret = packet_header_create(&request.header, sizeof(request), INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_EDGE_COUNT, device_p->ipcon_p, device_p);
00409
00410 if (ret < 0) {
00411 return ret;
00412 }
00413
00414 request.pin = pin;
00415 request.reset_counter = reset_counter;
00416
00417 ret = device_send_request(device_p, (Packet *)&request, (Packet *)&response);
00418
00419 if (ret < 0) {
00420 return ret;
00421 }
00422 *ret_count = leconvert_uint32_from(response.count);
00423
00424
00425
00426 return ret;
00427 }
00428
00429 int industrial_digital_in_4_set_edge_count_config(IndustrialDigitalIn4 *industrial_digital_in_4, uint16_t selection_mask, uint8_t edge_type, uint8_t debounce) {
00430 DevicePrivate *device_p = industrial_digital_in_4->p;
00431 SetEdgeCountConfig_ request;
00432 int ret;
00433
00434 ret = packet_header_create(&request.header, sizeof(request), INDUSTRIAL_DIGITAL_IN_4_FUNCTION_SET_EDGE_COUNT_CONFIG, device_p->ipcon_p, device_p);
00435
00436 if (ret < 0) {
00437 return ret;
00438 }
00439
00440 request.selection_mask = leconvert_uint16_to(selection_mask);
00441 request.edge_type = edge_type;
00442 request.debounce = debounce;
00443
00444 ret = device_send_request(device_p, (Packet *)&request, NULL);
00445
00446
00447 return ret;
00448 }
00449
00450 int industrial_digital_in_4_get_edge_count_config(IndustrialDigitalIn4 *industrial_digital_in_4, uint8_t pin, uint8_t *ret_edge_type, uint8_t *ret_debounce) {
00451 DevicePrivate *device_p = industrial_digital_in_4->p;
00452 GetEdgeCountConfig_ request;
00453 GetEdgeCountConfigResponse_ response;
00454 int ret;
00455
00456 ret = packet_header_create(&request.header, sizeof(request), INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_EDGE_COUNT_CONFIG, device_p->ipcon_p, device_p);
00457
00458 if (ret < 0) {
00459 return ret;
00460 }
00461
00462 request.pin = pin;
00463
00464 ret = device_send_request(device_p, (Packet *)&request, (Packet *)&response);
00465
00466 if (ret < 0) {
00467 return ret;
00468 }
00469 *ret_edge_type = response.edge_type;
00470 *ret_debounce = response.debounce;
00471
00472
00473
00474 return ret;
00475 }
00476
00477 int industrial_digital_in_4_get_identity(IndustrialDigitalIn4 *industrial_digital_in_4, char ret_uid[8], char ret_connected_uid[8], char *ret_position, uint8_t ret_hardware_version[3], uint8_t ret_firmware_version[3], uint16_t *ret_device_identifier) {
00478 DevicePrivate *device_p = industrial_digital_in_4->p;
00479 GetIdentity_ request;
00480 GetIdentityResponse_ response;
00481 int ret;
00482
00483 ret = packet_header_create(&request.header, sizeof(request), INDUSTRIAL_DIGITAL_IN_4_FUNCTION_GET_IDENTITY, device_p->ipcon_p, device_p);
00484
00485 if (ret < 0) {
00486 return ret;
00487 }
00488
00489
00490 ret = device_send_request(device_p, (Packet *)&request, (Packet *)&response);
00491
00492 if (ret < 0) {
00493 return ret;
00494 }
00495 strncpy(ret_uid, response.uid, 8);
00496 strncpy(ret_connected_uid, response.connected_uid, 8);
00497 *ret_position = response.position;
00498 memcpy(ret_hardware_version, response.hardware_version, 3 * sizeof(uint8_t));
00499 memcpy(ret_firmware_version, response.firmware_version, 3 * sizeof(uint8_t));
00500 *ret_device_identifier = leconvert_uint16_from(response.device_identifier);
00501
00502
00503
00504 return ret;
00505 }
00506
00507 #ifdef __cplusplus
00508 }
00509 #endif