From afdb43513c0b0048c51cbc5ffa73ef7c64c0b45b Mon Sep 17 00:00:00 2001 From: Lee Ballard Date: Mon, 18 Feb 2019 21:21:01 -0600 Subject: [PATCH] #8: replace busy polling with pthread_cond_wait removed delays from PDA init and PDA get status --- aq_programmer.c | 56 ++++++++++++++++++++++++++++----------------- aq_programmer.h | 4 ++-- pda_aq_programmer.c | 6 ++--- pda_menu.c | 13 ++++++++--- pda_menu.h | 8 +++++++ 5 files changed, 58 insertions(+), 29 deletions(-) diff --git a/aq_programmer.c b/aq_programmer.c index 5263e19..550ddff 100644 --- a/aq_programmer.c +++ b/aq_programmer.c @@ -36,7 +36,6 @@ bool select_sub_menu_item(struct aqualinkdata *aq_data, char* item_string); bool select_menu_item(struct aqualinkdata *aq_data, char* item_string); -//void send_cmd(unsigned char cmd, struct aqualinkdata *aq_data); void cancel_menu(); @@ -54,9 +53,6 @@ void *set_aqualink_light_colormode( void *ptr ); void *set_aqualink_PDA_init( void *ptr ); void *set_aqualink_SWG( void *ptr ); -//void *get_aqualink_PDA_device_status( void *ptr ); -//void *set_aqualink_PDA_device_on_off( void *ptr ); - bool waitForButtonState(struct aqualinkdata *aq_data, aqkey* button, aqledstate state, int numMessageReceived); //bool waitForMessage(struct aqualinkdata *aq_data, char* message, int numMessageReceived); @@ -68,9 +64,9 @@ bool push_aq_cmd(unsigned char cmd); int _stack_place = 0; unsigned char _commands[MAX_STACK]; //unsigned char pgm_commands[MAX_STACK]; -unsigned char _pgm_command = NUL; - -bool _last_sent_was_cmd = false; +static unsigned char _pgm_command = NUL; +static pthread_mutex_t _pgm_command_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t _pgm_command_sent_cond = PTHREAD_COND_INITIALIZER; // External view of adding to queue void aq_send_cmd(unsigned char cmd) { @@ -99,18 +95,22 @@ int get_aq_cmd_length() unsigned char pop_aq_cmd(struct aqualinkdata *aq_data) { + static bool _last_sent_was_cmd = false; + unsigned char cmd = NUL; //logMessage(LOG_DEBUG, "pop_aq_cmd\n"); // :TODO: is this true for PDA? // can only send a command every other ack. - - if (_last_sent_was_cmd == true) { + if (!pda_mode() && (_last_sent_was_cmd == true)) { _last_sent_was_cmd= false; } else if (aq_data->active_thread.thread_id != 0) { + pthread_mutex_lock(&_pgm_command_mutex); cmd = _pgm_command; _pgm_command = NUL; logMessage(LOG_DEBUG, "pop_aq_cmd '0x%02hhx' (programming)\n", cmd); + pthread_cond_signal(&_pgm_command_sent_cond); + pthread_mutex_unlock(&_pgm_command_mutex); } else if (_stack_place > 0) { cmd = _commands[0]; @@ -394,7 +394,7 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr } - int ret; + int ret = 0; struct timespec max_wait; clock_gettime(CLOCK_REALTIME, &max_wait); max_wait.tv_sec += 30; @@ -1199,20 +1199,34 @@ void send_cmd(unsigned char cmd, struct aqualinkdata *aq_data) } */ -void send_cmd(unsigned char cmd) +bool send_cmd(unsigned char cmd) { - int i=0; - // If there is an unsent command, wait. - while ( (_pgm_command != NUL) && ( i++ < 10) ) { - //sleep(1); // NSF Change to smaller time. - //logMessage(LOG_ERR, "******** QUEUE IS FULL ******** delay\n", pgm_command); - delay(500); - } - - _pgm_command = cmd; - //delay(200); + bool ret=true; + int pret = 0; + struct timespec max_wait; + + clock_gettime(CLOCK_REALTIME, &max_wait); + max_wait.tv_sec += 5; + pthread_mutex_lock(&_pgm_command_mutex); + _pgm_command = cmd; logMessage(LOG_INFO, "Queue send '0x%02hhx' to controller (programming)\n", _pgm_command); + while (_pgm_command != NUL) + { + if ((pret = pthread_cond_timedwait(&_pgm_command_sent_cond, + &_pgm_command_mutex, &max_wait))) + { + logMessage (LOG_ERR, "send_cmd 0x%02hhx err %s\n", + cmd, strerror(pret)); + ret = false; + break; + } + } + if (ret) { + logMessage(LOG_INFO, "sent '0x%02hhx' to controller\n", _pgm_command); + } + pthread_mutex_unlock(&_pgm_command_mutex); + return ret; } /* diff --git a/aq_programmer.h b/aq_programmer.h index 532d42f..c1944be 100644 --- a/aq_programmer.h +++ b/aq_programmer.h @@ -59,7 +59,8 @@ void aq_send_cmd(unsigned char cmd); unsigned char pop_aq_cmd(struct aqualinkdata *aq_data); //bool push_aq_cmd(unsigned char cmd); -//void send_cmd(unsigned char cmd, struct aqualinkdata *aq_data); +bool send_cmd(unsigned char cmd); + //void cancel_menu(struct aqualinkdata *aq_data); //void *set_aqualink_time( void *ptr ); @@ -70,7 +71,6 @@ int setpoint_check(int type, int value, struct aqualinkdata *aqdata); const char *ptypeName(program_type type); // These shouldn't be here, but just for the PDA AQ PROGRAMMER -void send_cmd(unsigned char cmd); bool push_aq_cmd(unsigned char cmd); void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, program_type type); void cleanAndTerminateThread(struct programmingThreadCtrl *threadCtrl); diff --git a/pda_aq_programmer.c b/pda_aq_programmer.c index 9ebe1c1..aef0cfa 100644 --- a/pda_aq_programmer.c +++ b/pda_aq_programmer.c @@ -445,12 +445,12 @@ void *set_aqualink_PDA_device_on_off( void *ptr ) // If single config (Spa OR pool) rather than (Spa AND pool) heater is TEMP1 and TEMP2 if (aq_data->single_device == TRUE && device == POOL_HEAT_INDEX) { // rename Heater and Spa - sprintf(device_name,"%-13s\n","TEMP1"); + snprintf(device_name, sizeof(device_name), "%-13s\n","TEMP1"); } else if (aq_data->single_device == TRUE && device == SPA_HEAT_INDEX) {// rename Heater and Spa - sprintf(device_name,"%-13s\n","TEMP2"); + snprintf(device_name, sizeof(device_name), "%-13s\n","TEMP2"); } else { //Pad name with spaces so something like "SPA" doesn't match "SPA BLOWER" - sprintf(device_name,"%-13s\n",aq_data->aqbuttons[device].pda_label); + snprintf(device_name, sizeof(device_name), "%-13s\n",aq_data->aqbuttons[device].pda_label); } if ( find_pda_menu_item(aq_data, device_name, 13) ) { diff --git a/pda_menu.c b/pda_menu.c index 99abce3..1985f74 100644 --- a/pda_menu.c +++ b/pda_menu.c @@ -154,15 +154,22 @@ pda_menu_type pda_m_type() /* +--- FW Version --- +Line 0 = +Line 1 = PDA-PS4 Combo +Line 2 = +Line 3 = Firmware Version +Line 4 = +Line 5 = PPD: PDA 1.2 --- Main Menu --- -Line 0 = -Line 1 = AIR +Line 0 = +Line 1 = AIR (Line 4 first, Line 2 last, Highligh when finished) --- Equiptment Status --- Line 0 = EQUIPMENT STATUS (Line 0 is first. No Highlight, everything in list is on) --- Equiptment on/off menu -- -Line 0 = EQUIPMENT +Line 0 = EQUIPMENT (Line 0 is first. Highlight when complete) */ diff --git a/pda_menu.h b/pda_menu.h index 92dff24..311ee5c 100644 --- a/pda_menu.h +++ b/pda_menu.h @@ -4,6 +4,7 @@ #define PDA_LINES 10 // There is only 9 lines, but add buffer to make shifting easier +#define PDA_MAX_MENU_DEPTH 4 typedef enum pda_menu_type { PM_UNKNOWN, @@ -30,6 +31,13 @@ typedef enum pda_menu_type { PM_PALM_OPTIONS // This seems to be only older revisions } pda_menu_type; +// PDA Line 4 = POOL MODE OFF +// PDA Line 5 = POOL HEATER OFF +// PDA Line 6 = SPA MODE OFF +// PDA Line 7 = SPA HEATER OFF +// PDA Line 8 = MENU +// PDA Line 9 = EQUIPMENT ON/OFF + /* typedef enum pda_home_menu_item { PMI_MAIN,