Skip to content

Commit

Permalink
Adding everything
Browse files Browse the repository at this point in the history
  • Loading branch information
preston-rogers committed Sep 5, 2024
1 parent 158c175 commit 4aa3e30
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 8 deletions.
111 changes: 108 additions & 3 deletions src/jsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "jsd/jsd_el1008.h"
#include "jsd/jsd_el2124.h"
#include "jsd/jsd_el2809.h"
#include "jsd/jsd_el2828.h"
#include "jsd/jsd_el2798.h"
#include "jsd/jsd_el3104.h"
#include "jsd/jsd_el3162.h"
#include "jsd/jsd_el3202.h"
Expand All @@ -19,6 +21,7 @@
#include "jsd/jsd_el3356.h"
#include "jsd/jsd_el3602.h"
#include "jsd/jsd_el4102.h"
#include "jsd/jsd_el5042.h"
#include "jsd/jsd_epd_nominal.h"
#include "jsd/jsd_epd_sil.h"
#include "jsd/jsd_ild1900.h"
Expand Down Expand Up @@ -83,7 +86,7 @@ void jsd_set_slave_config(jsd_t* self, uint16_t slave_id,
self->slave_configs[slave_id] = slave_config;
}

bool jsd_init(jsd_t* self, const char* ifname, uint8_t enable_autorecovery) {
bool jsd_init(jsd_t* self, const char* ifname, uint8_t enable_autorecovery, int timeout_us) {
assert(self);
self->enable_autorecovery = enable_autorecovery;

Expand Down Expand Up @@ -164,15 +167,35 @@ bool jsd_init(jsd_t* self, const char* ifname, uint8_t enable_autorecovery) {

self->ecx_context.slavelist[0].state = EC_STATE_OPERATIONAL;


struct timespec start_processdata_time;
clock_gettime(CLOCK_REALTIME, &start_processdata_time);
ecx_send_overlap_processdata(&self->ecx_context);
ecx_receive_processdata(&self->ecx_context, EC_TIMEOUTRET);
ecx_receive_processdata(&self->ecx_context, timeout_us);

ecx_writestate(&self->ecx_context, 0);

int attempt = 0;
while (true) {
struct timespec current_time;
clock_gettime(CLOCK_REALTIME, &current_time);
if ((start_processdata_time.tv_nsec - current_time.tv_nsec)/1e3 > timeout_us) {
MSG_DEBUG("Went over the loop period!");
}
else {
struct timespec diff;
diff.tv_sec = current_time.tv_sec - start_processdata_time.tv_sec;
diff.tv_nsec = current_time.tv_nsec - start_processdata_time.tv_nsec;
if (nanosleep(&diff, NULL) < 0) {
perror("nanosleep failed");
return 1;
}
}

clock_gettime(CLOCK_REALTIME, &start_processdata_time);
int sent = ecx_send_overlap_processdata(&self->ecx_context);
int wkc = ecx_receive_processdata(&self->ecx_context, EC_TIMEOUTRET);
int wkc = ecx_receive_processdata(&self->ecx_context, timeout_us);

ec_state actual_state = ecx_statecheck(
&self->ecx_context, 0, EC_STATE_OPERATIONAL, EC_TIMEOUTSTATE);

Expand All @@ -194,6 +217,8 @@ bool jsd_init(jsd_t* self, const char* ifname, uint8_t enable_autorecovery) {
WARNING("Failed OP transition attempt %d of %d", attempt,
JSD_PO2OP_MAX_ATTEMPTS);

jsd_inspect_context(self);

if (attempt >= JSD_PO2OP_MAX_ATTEMPTS) {
ERROR("Max number of attempts to transition to OPERATIONAL exceeded.");
return false;
Expand Down Expand Up @@ -226,6 +251,61 @@ bool jsd_init(jsd_t* self, const char* ifname, uint8_t enable_autorecovery) {
return true;
}

bool jsd_all_slaves_operational(jsd_t* self) {
int slave;
bool all_slaves_operational = true;
uint8_t currentgroup = 0; // only 1 rate group in JSD currently
/* one or more slaves may not be responding */
for (slave = 1; slave <= *self->ecx_context.slavecount; slave++) {
if (self->ecx_context.slavelist[slave].group != currentgroup) continue;
/* re-check bad slave individually */
ecx_statecheck(&self->ecx_context, slave, EC_STATE_OPERATIONAL, EC_TIMEOUTRET);
if (self->ecx_context.slavelist[slave].state != EC_STATE_OPERATIONAL) {
all_slaves_operational = false;
if (self->ecx_context.slavelist[slave].state ==
(EC_STATE_SAFE_OP + EC_STATE_ERROR)) {
ERROR("slave[%d] is in SAFE_OP + ERROR.", slave);
} else if (self->ecx_context.slavelist[slave].state == EC_STATE_SAFE_OP) {
ERROR("slave[%d] is in SAFE_OP.", slave);
} else if (self->ecx_context.slavelist[slave].state > EC_STATE_NONE) {
ERROR("slave[%d] is in state with hexadecimal: %x", slave, self->ecx_context.slavelist[slave].state);
} else {
ERROR("slave[%d] is lost", slave);
}
}
else {
MSG("slave[%d] is OPERATIONAL.", slave);
}
}

return all_slaves_operational;
}

void jsd_inspect_context(jsd_t* self) {
ec_state bus_state = jsd_get_device_state(self, 0);

/* first check if the jsd bus is operational so we can get more info */
if (bus_state != EC_STATE_OPERATIONAL) {
ERROR("JSD bus is not OPERATIONAL.");
}

if (jsd_all_slaves_operational(self)) {
MSG("All slaves were operational at time of working counter fault.");
}
else {
MSG("Some slaves were not operational.");
if (self->ecx_context.ecaterror) {
MSG("We experienced an ECAT error. When this occurs, error information aught to be saved. "
"Errors in error list displayed below:\n");
while(self->ecx_context.ecaterror) MSG("%s\n", ecx_elist2string(&self->ecx_context));
MSG("Went through all errors in the elist stack.\n");
}
else {
MSG("Despite some slaves not being operational, an ECAT error was not experienced.");
}
}
}

void jsd_read(jsd_t* self, int timeout_us) {
assert(self);

Expand Down Expand Up @@ -373,6 +453,10 @@ const char* jsd_driver_type_to_string(jsd_driver_type_t driver_type) {
return "JSD_DRIVER_TYPE_EL2124";
case JSD_DRIVER_TYPE_EL2809:
return "JSD_DRIVER_TYPE_EL2809";
case JSD_DRIVER_TYPE_EL2828:
return "JSD_DRIVER_TYPE_EL2828";
case JSD_DRIVER_TYPE_EL2798:
return "JSD_DRIVER_TYPE_EL2798";
case JSD_DRIVER_TYPE_EL3104:
return "JSD_DRIVER_TYPE_EL3104";
case JSD_DRIVER_TYPE_EL3162:
Expand All @@ -389,6 +473,8 @@ const char* jsd_driver_type_to_string(jsd_driver_type_t driver_type) {
return "JSD_DRIVER_TYPE_EL3602";
case JSD_DRIVER_TYPE_EL4102:
return "JSD_DRIVER_TYPE_EL4102";
case JSD_DRIVER_TYPE_EL5042:
return "JSD_DRIVER_TYPE_EL5042";
case JSD_DRIVER_TYPE_EPD_NOMINAL:
return "JSD_DRIVER_TYPE_EPD_NOMINAL";
case JSD_DRIVER_TYPE_EPD_SIL:
Expand Down Expand Up @@ -479,6 +565,12 @@ bool jsd_driver_is_compatible_with_product_code(jsd_driver_type_t driver_type,
case JSD_DRIVER_TYPE_EL2809:
is_compatible = jsd_el2809_product_code_is_compatible(product_code);
break;
case JSD_DRIVER_TYPE_EL2828:
is_compatible = jsd_el2828_product_code_is_compatible(product_code);
break;
case JSD_DRIVER_TYPE_EL2798:
is_compatible = jsd_el2798_product_code_is_compatible(product_code);
break;
case JSD_DRIVER_TYPE_EGD:
is_compatible = jsd_egd_product_code_is_compatible(product_code);
break;
Expand Down Expand Up @@ -509,6 +601,9 @@ bool jsd_driver_is_compatible_with_product_code(jsd_driver_type_t driver_type,
case JSD_DRIVER_TYPE_EL4102:
is_compatible = jsd_el4102_product_code_is_compatible(product_code);
break;
case JSD_DRIVER_TYPE_EL5042:
is_compatible = jsd_el5042_product_code_is_compatible(product_code);
break;
case JSD_DRIVER_TYPE_ILD1900:
is_compatible = jsd_ild1900_product_code_is_compatible(product_code);
break;
Expand Down Expand Up @@ -549,6 +644,12 @@ bool jsd_init_single_device(jsd_t* self, uint16_t slave_id) {
case JSD_DRIVER_TYPE_EL2809:
return jsd_el2809_init(self, slave_id);
break;
case JSD_DRIVER_TYPE_EL2828:
return jsd_el2828_init(self, slave_id);
break;
case JSD_DRIVER_TYPE_EL2798:
return jsd_el2798_init(self, slave_id);
break;
case JSD_DRIVER_TYPE_EL2124:
return jsd_el2124_init(self, slave_id);
break;
Expand Down Expand Up @@ -576,6 +677,9 @@ bool jsd_init_single_device(jsd_t* self, uint16_t slave_id) {
case JSD_DRIVER_TYPE_EL4102:
return jsd_el4102_init(self, slave_id);
break;
case JSD_DRIVER_TYPE_EL5042:
return jsd_el5042_init(self, slave_id);
break;
case JSD_DRIVER_TYPE_ILD1900:
return jsd_ild1900_init(self, slave_id);
break;
Expand Down Expand Up @@ -650,3 +754,4 @@ void jsd_ecatcheck(jsd_t* self) {
SUCCESS("all slaves resumed OPERATIONAL.");
}
}

18 changes: 17 additions & 1 deletion src/jsd_pub.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,22 @@ void jsd_set_slave_config(jsd_t* self, uint16_t slave_id,
* @param enable_autorecovery enables automatic recovery of lost devices
* @return true on successful SOEM initialization
*/
bool jsd_init(jsd_t* self, const char* ifname, uint8_t enable_autorecovery);
bool jsd_init(jsd_t* self, const char* ifname, uint8_t enable_autorecovery, int timeout_us);

/**
* @brief Determines if all slaves are operational via individual slave queries
*
* @param self pointer JSD context
*/
bool jsd_all_slaves_operational(jsd_t* self);

/**
* @brief After experiencing a bad working counter it is advised to check the
* context to discover which devices were problematic (if any).
*
* @param self pointer JSD context
*/
void jsd_inspect_context(jsd_t* self);

/**
* @brief Receive data from slave devices and store on local IOmap.
Expand Down Expand Up @@ -104,3 +119,4 @@ char* jsd_ec_state_to_string(ec_state state);
#endif

#endif

2 changes: 1 addition & 1 deletion test/device/jsd_minimal_example_el3602.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ int main() {
jsd_set_slave_config(jsd, slave_id, my_config);

// Slave configuration must come before initialization
if (!jsd_init(jsd, "eth9", 1)) {
if (!jsd_init(jsd, "eth9", 1, EC_TIMEOUTRET)) {
ERROR("Could not init jsd");
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion test/jsd_test_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void sds_run(single_device_server_t* self, char* device_name, char* filename) {

uint32_t sds_iter = 0;

if (!jsd_init(self->jsd, device_name, 1)) {
if (!jsd_init(self->jsd, device_name, 1, EC_TIMEOUTRET)) {
ERROR("Could not init jsd");
return;
}
Expand Down
2 changes: 1 addition & 1 deletion test/unit/jsd_soem_init_close_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ int main(int argc, char* argv[]) {

jsd_t* jsd = jsd_alloc();

if (!jsd_init(jsd, argv[1], 1)) {
if (!jsd_init(jsd, argv[1], 1, EC_TIMEOUTRET)) {
ERROR("Could not init jsd");
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion tools/jsd_egd_tlc_tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ int main(int argc, char* argv[]) {
jsd_set_slave_config(jsd, slave_id, my_config);

// slave configuration must come before initialization
if (!jsd_init(jsd, ifname, 1)) {
if (!jsd_init(jsd, ifname, 1, EC_TIMEOUTRET)) {
ERROR("Could not init jsd");
return 0;
}
Expand Down

0 comments on commit 4aa3e30

Please sign in to comment.